递归的定义:

递归的定义:你打开面前这扇门,看到屋里面还有一扇门。你走过去,发现手中的钥匙还可以打开它,你推开门,
发现里面还有一扇门,你继续打开它。若干次之后,你打开面前的门后,发现只有一间屋子,没有门了。然后,
你开始原路返回,每走回一间屋子,你数一次,走到入口的时候,你可以回答出你到底用这你把钥匙打开了几扇门。循环
:你打开面前这扇门,看到屋里面还有一扇门。你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门(
若前面两扇门都一样,那么这扇门和前两扇门也一样;如果第二扇门比第一扇门小,那么这扇门也比第二扇门小,你继续打开这扇门,一
直这样继续下去直到打开所有的门。但是,入口处的人始终等不到你回去告诉他答案。上面的比喻形象地阐述了递归与循环的内涵,那么我们来思
考以下几个问题:
什么是递归呢?
递归的精髓(思想)是什么?
递归和循环的区别是什么?
什么时候该用递归?
使用递归需要注意哪些问题?递归思想解决了哪些经典的问题?
这些问题正是笔者准备在本文中详细阐述的问题。
二. 递归的内涵1、定义 (什么是递归?)在数学与计算机科学中,递归(Recursion)是指在函数
的定义中使用函数自身的方法。实际上,递归,顾名思义,其包含了两个意思:递 和 归,这正是递归思想的精华所在。
2、递归思想的内涵(递归的精髓是什么?)正如上面所描述的场
景,递归就是有去(递去)有回(归来)
,如下图所示。“有去”是指:递归问题必须可以分解为若干个规模较小,与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决,就
像上面例子中的钥匙可以打开后面所有门上的锁一样;“有回”是指 : 这些问题的演化过程是一个从大到小,由近及远的过程,并且会有一个明确的终点(临界点),一旦到达了这个临界点,
就不用再往更小、更远的地方走下去。
最后,从这
个临界点开始,原路返回到原点,原问题解决。

第一题了解递归:

package 第七章递归知识讲解;
/*** 递归的定义:你打开面前这扇门,看到屋里面还有一扇门。你走过去,发现手中的钥匙还可以打开它,你推开门,
发现里面还有一扇门,你继续打开它。若干次之后,你打开面前的门后,发现只有一间屋子,没有门了。然后,
你开始原路返回,每走回一间屋子,你数一次,走到入口的时候,你可以回答出你到底用这你把钥匙打开了几扇门。循环
:你打开面前这扇门,看到屋里面还有一扇门。你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门(
若前面两扇门都一样,那么这扇门和前两扇门也一样;如果第二扇门比第一扇门小,那么这扇门也比第二扇门小,你继续打开这扇门,一
直这样继续下去直到打开所有的门。但是,入口处的人始终等不到你回去告诉他答案。上面的比喻形象地阐述了递归与循环的内涵,那么我们来思
考以下几个问题:
什么是递归呢?
递归的精髓(思想)是什么?
递归和循环的区别是什么?
什么时候该用递归?
使用递归需要注意哪些问题?递归思想解决了哪些经典的问题?
这些问题正是笔者准备在本文中详细阐述的问题。
二. 递归的内涵1、定义 (什么是递归?)在数学与计算机科学中,递归(Recursion)是指在函数
的定义中使用函数自身的方法。实际上,递归,顾名思义,其包含了两个意思:递 和 归,这正是递归思想的精华所在。
2、递归思想的内涵(递归的精髓是什么?)正如上面所描述的场
景,递归就是有去(递去)有回(归来)
,如下图所示。“有去”是指:递归问题必须可以分解为若干个规模较小,与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决,就
像上面例子中的钥匙可以打开后面所有门上的锁一样;“有回”是指 : 这些问题的演化过程是一个从大到小,由近及远的过程,并且会有一个明确的终点(临界点),一旦到达了这个临界点,
就不用再往更小、更远的地方走下去。
最后,从这
个临界点开始,原路返回到原点,原问题解决。* @author MZFAITHDREAM**/
public class 递归0 {
/*** 什么是递归自己调用自己,利用加法。来看看什么是递归* @param args*/public static void main(String[] args) {// TODO Auto-generated method stubint n=sum_recursion(1, 3);//1+2+3+4+5+6=21System.out.println(sum_recursion(n, n));/*** @author MZFAITHDREAM* 定义一个- 法*/int m=sum_recursion1(6, 1);System.out.println(sum_recursion1(m, m));}private static int sum_recursion1(int end, int start) {if(end==start) {return start;} return end-sum_recursion1(end-1, start);
}private static int sum_recursion(int start,int end) {// TODO Auto-generated method stubif(start==end) {return end;}
//              自己调用自己return start+sum_recursion(start+1, end);}}

第二题双管齐下解决递归问题。

package 第七章递归知识讲解;
/*** 第七章第一课* 7.2 双管齐下解决递归问题* 上楼梯问题* @author MZFAITHDREAM**/
public class 递归2 {public static void main(String[] args) {System.out.println(f1(39));}//用递归public static long f1(int n) {if(n<0) return 0;if(n==0||n==1) return 1;if(n==2) return 2;return f1(n-1)+f1(n-2);}}

第三题企面试题:硬币表示某个给定数值。

package 第七章递归知识讲解;
/*** 7.4 名企面试题:硬币表示某个给定数值* 循环中递归* @author MZFAITHDREAM**
假设我们有8种不同面值的硬币{1,2,5,10,20,50,100,200},
用这些硬币组合够成一个给定的数值n。例如n=200,那么一种可能的组合
方式为 200 = 3 * 1 + 1*2 + 1*5 + 2*20 + 1 * 50 + 1 * 100.
问总共有多少种可能的组合方式?
2、华为面试题
1分2分5分三种硬币,组成已一角/共有多少解法
3.cc150 给出 1 5 10 25 有多少种方法
*/
public class 递归3 {public static void main(String[] args) {int res=countWays(15);System.out.println(res);}public static int countWays(int n) {//输入面值if(n<=0) {//如果小于零return 0;}//定义总价    数组面值        下标return countWaysCore(n,new int[] {1,2,5,10,20,50,100,200},7);}//代入private static int countWaysCore(int n,int[]coins,int cur) {if(cur==0) {return 1;}int res=0;//要么不选, 可以选1 2  3 4 for(int i=0;i*coins[cur]<=n;i++) {//100 25 *4 iint shenyu=n-i*coins[cur];//取大的多少个res+=countWaysCore(shenyu,coins,cur-1);//递归+}return res;  }
}

第四题“逐步生成结果”之非数值型问题。

package 第七章递归知识讲解;import java.util.HashSet;
import java.util.Set;/*** 7.5 “逐步生成结果”之非数值型问题* @author MZFAITHDREAM**/
public class 递归4 {//递归public static Set<String> kuohao1(int m){Set<String> s_M=new HashSet<>();  //因为set可以去重复if(m==1) {s_M.add("()");return s_M;}Set<String> set_m_1=kuohao1(m-1); //调m-1层,添加元素for (String s : set_m_1) {s_M.add("()"+s);s_M.add(s+"()");s_M.add("("+s+")");}return s_M;}//迭代public static Set<String> kuohao2(int m){Set<String> res=new HashSet<>();res.add("()");if(m==1) return res;  for (int i = 2; i <=m; i++) {Set<String> res_new=new HashSet<>();  //创建一个新的集合用于存储上一个集合更新后的结果for (String s : res) {  //添加res_new.add("()"+s);res_new.add(s+"()");res_new.add("("+s+")");}res=res_new; //更新集合}return res;}public static void main(String[] args) {Set<String> kuohao1 = kuohao1(8);for (String s : kuohao1) {System.out.print(s+"    ");}System.out.println();Set<String> kuohao2 = kuohao2(3);for (String s : kuohao2) {System.out.print(s+"    ");}}
}

第五题 子集生成

package 第七章递归知识讲解;import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;/*** 7.6 子集生成* @author MZFAITHDREAM* 给定一个数组A和数组的大小int n,请返回A的所有非空子集。**//*** 2的n次方-1* arr目标数组* cur:数组下标1* @author MZFAITHDREAM**/
public class 递归6 {public static void main(String[] args) {递归6 obj=new 递归6();int[] a= {1,2,3};Set<Set<Integer>> subSets=obj.getSubset(a,a.length);System.out.println(subSets);}public Set<Set<Integer>> getSubset(int[] a,int n){return solve(a,n,n-1);}private static Set<Set<Integer>> solve(int[] a, int n, int cur) {/*** 下面是大集合* 对每一个元素 建立集合*/Set<Set<Integer>> newset=new HashSet<>();/*** 判断*/if(cur==0) {Set<Integer> nil=new HashSet<>();//空集Set<Integer> first=new HashSet<>();//第一个元素first.add(a[0]);newset.add(nil);newset.add(first);return newset;}
//        大集合里面Set<Set<Integer>> oldset=solve(a,n,cur-1);for(Set<Integer> set:oldset){//对于每个子集cur下标对应的元素可以加进去也可以不加进去newset.add(set);//保留原样Set<Integer> clone=(Set<Integer>)((HashSet)set).clone();//拷贝setclone.add(a[cur]);//添加当前元素newset.add(clone);}return newset;}}

第六题子集生成之二进制法。

package 第七章递归知识讲解;import java.util.HashSet;
import java.util.Set;/*** 7.6 子集生成之二进制法* @author MZFAITHDREAM***/
public class 递归7 {private static Set<Set<Integer>> newSet;public static void main(String[] args) {
//      调用自己定义的方法int [] A= {123,456,789};Set<Set<Integer>> set=new 递归7().getSubset(A, A.length);System.out.println(set);}public static Set<Set<Integer>> getSubset(int[] A,int n){return solve(A,n,n-1);}/*** 递归增量构造法* @param A* @param n* @param cur* @return */private static Set<Set<Integer>> solve(int[] A, int n, int cur) {if(cur==0) {//处理第一个元素
//      nullSet<Integer> nil=new HashSet();
//      fistSet<Integer> fist=new HashSet();fist.add(A[0]);newSet.add(nil);newSet.add(fist);try {Set<Set<Integer>> oldSet =getSubset(A, n);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}Set<Set<Integer>> newSet =new HashSet();for (Set<Integer> set : newSet) {
//      对于每个子集,cur这个元素可以加进去,也可以不加进去newSet.add(set);//保留原样
//      set转为HashSetSet<Integer>clone= (Set<Integer>) ((HashSet)set).clone();
//  上面是技术克隆 clone.add(A[cur]); //增加元素newSet.add(clone);} return  newSet;}return newSet;}
}

7.7 子集生成之二进制法。

package 第七章递归知识讲解;import java.util.HashSet;
import java.util.Set;/*** 7.7 子集生成之二进制法* @author MZFAITHDREAM**2的n次方-1*/
public class 递归71 {public static void main(String[] args) {Object[] arr = {1,2,3};Set<Set<Object>> subSets = getSubSets( arr,arr.length-1);       subSets.remove(new HashSet<Object>());//移除空集System.out.println(subSets);}/** arr:目标数组* cur:正在操作的数组元素下标 */public static Set<Set<Object>> getSubSets(Object[] arr,int cur) {//当前元素对应的结果,Set<Set<Object>> newSet = new HashSet<Set<Object>>();if(cur == 0) {Set<Object> nil = new HashSet<Object>();//借助空集Set<Object> first = new HashSet<Object>();//只包含第一个元素的子集first.add(arr[cur]);newSet.add(nil);newSet.add(first);return newSet;}//上一个元素的结果Set<Set<Object>> oldSet = getSubSets(arr,cur-1);for (Set<Object> set : oldSet) {newSet.add(set);Set<Object> temp = new HashSet<Object>(set);temp.add(arr[cur]);newSet.add(temp);}return newSet;}/*** //递推实现:* @param args*/public static void main1(String[] args) {Object[] arr = {"c","d","a"};Set<Set<Object>> subSets = getSubSets( arr,arr.length-1);subSets.remove(new HashSet<Object>());System.out.println(subSets);}/* arr:目标数组* cur:正在操作的数组元素下标 */public static Set<Set<Object>> getSubSets1(Object[] arr,int cur) {//当前元素对应的结果,Set<Set<Object>> res_set = new HashSet<Set<Object>>();res_set.add(new HashSet<Object>());for (Object i : arr) {Set<Set<Object>> tempSet = new HashSet<Set<Object>>();tempSet.addAll(res_set);for (Set<Object> set : res_set) {Set<Object> temp = new HashSet<Object>(set);temp.add(i);tempSet.add(temp);}res_set = tempSet;}return res_set;}
}

第八题:全排列(上)

package 第七章递归知识讲解;
import java.util.ArrayList;
/*** 7.8 全排列(上)* @author MZFAITHDREAM*给定一个字符串String s = "abc";求s的全排列
递归实现:
对于字符串s的全排列可以再s.length()-1的字符串全排列基础上放左边,放右边和放中间几种方式实现*/
import java.util.HashSet;
import java.util.Set;public class 递归8 {public static void main(String[] args) {Set<String>res=new 递归8().getPermutations("ab");System.out.println(res);System.out.println("----------------------全排列方式------------------------------------");Set<String>re=new 递归8().getPermutations1("abc");System.out.println(re);}/*** *全排列* @param str* @return*/public static Set<String> getPermutations1(String str) {//当前元素对应的结果,Set<String> res_set = new HashSet<String>();
//      判断长度==1if(str.length()==1) {res_set.add(str);return res_set;}//字符串长度-1的全排列Set<String> pre_set =getPermutations1(str.substring(0,str.length()-1));String addStr = str.charAt(str.length()-1)+"";//需要添加的字符串for (String s : pre_set) {//放左边String tempStr = addStr+s;res_set.add(tempStr);//放右边tempStr = s+addStr;res_set.add(tempStr);//放中间for (int j = 1; j < s.length(); j++) {tempStr = s.substring(0,j)+addStr+s.substring(j);res_set.add(tempStr);}}return res_set;}/*** 递推实现:* @param str* @return*/public static Set<String> getPermutations(String str) {//当前元素对应的结果,Set<String> res_set = new HashSet<String>();res_set.add(str.substring(0,1));if(str.length()==1) {return res_set;}for (int i = 1; i < str.length(); i++) {Set<String> tempSet = new HashSet<String>();String addStr = str.substring(i,i+1);for (String s : res_set) {//放左边String tempStr = addStr+s;tempSet.add(tempStr);//放右边tempStr = s+addStr;tempSet.add(tempStr);//放中间for (int j = 1; j < s.length(); j++) {tempStr = s.substring(0,j)+addStr+s.substring(j);tempSet.add(tempStr);}}res_set = tempSet;}return res_set;}}

全排列(中)

package 第七章递归知识讲解;import java.util.HashSet;
import java.util.Set;/*** 7.8 全排列(中)* @author MZFAITHDREAM**/
public class 递归9 {public static void main(String[] args) {Set<String>res=    new 递归9().getPermutations("abcdef".toCharArray(),3);System.out.println(res);}private static Set<String> res = new HashSet();;public static Set<String> getPermutations(char[] charArr,int k) {if(k==charArr.length) {res.add(new String(charArr));}for (int i = k; i < charArr.length; i++) {swap(charArr,k,i);getPermutations(charArr,k+1);//将剩余元素一次放在k+1位置swap(charArr,k,i);//还原(回溯)}return res;}static void swap(char[] charArr,int i,int j) {char temp = charArr[i];charArr[i] = charArr[j];charArr[j] = temp;}}

全排列(下)

package 第七章递归知识讲解;
/*** 7.8 全排列(下)* @author MZFAITHDREAM**/
public class 递归10 {/*** 前缀法* @param args*/public static void main(String[] args) {permutations("","abc");}final static int k = 5;static int count = 0;public static void permutations(String prefix,String target) {if(prefix.length() == target.length()) {count++;if(count==k) {System.out.println(prefix);System.exit(0);}}for (int i = 0; i < target.length(); i++) {char ch = target.charAt(i);if(!prefix.contains(ch+"")) {permutations(prefix+ch,target);}}}}

第七章递归知识讲解。相关推荐

  1. 第七章 查找 知识导图

    第七章知识导图:

  2. unixlinux大学教程学习 第七章

    unix&linux大学教程学习 第七章 学习了第七章. 主要讲解键盘信号 每一个键盘对应一个信号.主要的有: ^代表 Ctrl <Backspance> erase ,删除一个字 ...

  3. DSt:数据结构的最强学习路线之数据结构知识讲解与刷题平台、刷题集合、问题为导向的十大类刷题算法(数组和字符串、栈和队列、二叉树、堆实现、图、哈希表、排序和搜索、动态规划/回溯法/递归/贪心/分治)总

    DSt:数据结构的最强学习路线之数据结构知识讲解与刷题平台.刷题集合.问题为导向的十大类刷题算法(数组和字符串.栈和队列.二叉树.堆实现.图.哈希表.排序和搜索.动态规划/回溯法/递归/贪心/分治)总 ...

  4. NPDP知识推送-第七章产品生周期管理(3)

    NPDP知识推送-第七章产品生周期管理-3 7.2.1可持续产品创新 7.2.2产品开发中的可持续性 7.2整个一大节介绍了一些可持续相关的概念,非常粗泛 对于考试,都是概念题,大家了解.区分各个概念 ...

  5. NPDP知识推送-第七章产品生周期管理(1)

    NPDP知识推送-第七章产品生周期管理-1 7.1产品生命周期管理 7.1.1产品生命周期简介(答案:1C 3A) 7.1.2管理产品生命周期(答案:5A 9A) 7.1.3产品生命周期的影响和产品组 ...

  6. NPDP知识推送-第七章产品生周期管理(2)

    NPDP知识推送-第七章产品生周期管理-2 7.1产品生命周期管理 7.1.4产品引入的关键阶段(答案:6A 143B) 7.1.5"新式路径"的案例 (答案:7A 15A)

  7. NPDP知识推送-第七章产品生周期管理(4)

    NPDP知识推送-第七章产品生周期管理-4 7.2.3可持续性工具 7.2.4生命周期评估的案例研究和认证 同样是几个概念,与昨天的几个区分开,标红的是相对重要的.

  8. 谭浩强C语言第七章知识总结

    第七章 定义函数 定义没有参数的函数, 类型名 函数名()               类型名  函数名(void) {                                { 函数体    ...

  9. 《微机原理第五版》期末知识总结(第五章---第七章)

    微机原理与接口技术 本文承接上篇前四章的内容,对第五章到第七章做个期末总结,方便大家更好的掌握这门课的知识点.看到了这里说明你对这门课程还有很大的兴趣和执念,另外有配套的试题和PPT在我的主页可以翻阅 ...

  10. 第七章 Java基础类库

    前言:如果你真正学习到了这里,那么先容许我夸赞一下你,太棒了!哪怕你对前面六篇文章的掌握度达到50%也是非常了不起的了,关于后面的文章学习我只能说,非常简单,只是我们文章会非常详细的介绍实现原理和一些 ...

最新文章

  1. R语言ggplot2可视化:ggplot2可视化直方图(histogram)并在直方图的顶部外侧(top upper)或者直方图内部添加数值标签
  2. https原理与实践
  3. 数字进度条组件NumberProgressBar
  4. 「镁客早报」华为Mate 30最快今年9月推出;波士顿动力再秀Handle新动态
  5. Windows如何让一个窗口显示最前(窗口锁住最前)?TopMost
  6. Entity Framework 4.1(转)
  7. 【数据结构与算法】之深入解析Base64编码的实现原理
  8. 会畅通讯登陆创业板上市,CEO黄元庚说云视频是下一个万亿级市场
  9. 11.20,winfrom,增加,查询,删除,修改
  10. linux源代码剖析之lib
  11. 【阅读理解】机器阅读理解方向有什么值得follow的大佬,网站等等?
  12. 从看《长津湖》想到的数字化转型
  13. pip常用指令及numpy安装
  14. Java LeetCode每日一题-从易到难带你领略算法的魅力(七):Z 字形变换
  15. October CMS Vs Wordpress
  16. Gentoo安装教程(Systemd+Gnome)
  17. Scipy_常用统计函数
  18. 高德地图sdk设置marker并且将设置为地图中心
  19. Linux下的FireBird安装
  20. 南京邮电大学电工电子(数电)实验报告——计数器 移位寄存器

热门文章

  1. 女生专属树洞,树懒APP内测(附下载)
  2. 取向性完全不同 骐达英朗底盘对比解析
  3. 互联网常见错误代码(如404)
  4. python去掉标点、特殊符号_删除URL的Python列表末尾的特殊字符/标点符号
  5. opencv学习笔记(一) 环境配置/打开一张图片/github(git)初探
  6. 豆瓣250排行榜算法
  7. 【洛谷P3554】LUK-Triumphal arch【树形dp】【二分】
  8. C语言|计算流逝后的时间
  9. 开源帮助:什么是退出代码 137,你能修复它吗?
  10. 在html中打字如何变大,怎么把网页的字变大?教你网页操作实用技巧【步骤详解】...