关于递归方面的思想总结以及习题展示

汉诺塔游戏

 * **【题目】**
 * 三个柱子,其中一个柱子全是由小到大的盘子
 * 需要把这些盘子全部移动到另一个上并且顺序不变
 * 要求:一次移动一个并且大的只可以在小的下面
 *** 【算法思想】**:
 * 1,每次可以把第1~N-1个移到辅助柱子,第N个移动到目标柱子
 * 2,然后将原始柱子作为辅助柱子,辅助柱子作为原始柱子
 * 3,在进行第一步
 *** 【总结】**
 * 学习递归要整体化思想把拆分后的一部分看作一个整体来处理
 * 看到这个代码一直不明白,总是想把他代码套进去看一看
 * 假如有4层的汉诺塔,把前3层作为整体就感觉一切都是那么顺其自然了
 * 不必要担心前3层的操作,因为前3层在函数里面还会被分为第3层和前2层
 * 所以说只需要将事物整体化,才可以看明白递归,才可以遇到问题想出递归代码
public class 汉诺塔游戏 {

	public static void main(String[] args) {
		String A="A",B="B",C="C";
		printHanoiTower(4, A,C,B);
	}
public static void printHanoiTower(int N,String from,String to,String help){
	if(N==1){
		System.out.println("move"+N+"from"+from+"to"+to);
		return;
	}
	printHanoiTower(N-1, from, help,to);
	System.out.println("move "+N+" from "+from+" to "+to);
	printHanoiTower(N-1, help,to,from);
}
}

蓝桥杯题目

  • 【题目】
  • 这样的巧合情况可能还有很多,比如: 27 * 594 = 297 * 54
  • 假设a b C d e代表1~9不同的5个数字(注意是各不相同的数字,且不含0)
  • 能满足形如:abcde=adbce这样的算式一共有多少种呢?
  • 请你利用计算机的优势寻找所有的可能,并回答不同算式的种类数。
  • 满足乘法交换律的算式计为不同的种类,所以答案肯定是个偶数。
  • 【算法思想】
  • 分为2个函数来做
  • 1,算出1到l选k个数的所有可能组合
  • 2,排出每不同的5个数的所有排列顺序
    *【总结】
  • 先找/排出第1个数,再找/排第剩下的
  • 函数做一个for循环,剩下的函数调用函数
  • !!!要注意的就是要注意其中的变量值!!!
  • 我犯错的经常之处
public class 练习题 {
	static int max = 0;
	public static void main(String[] args) {
		int [] arr=new int[5];
		f1(1,9,5,0,arr);
		System.out.println(max);
		}
	//1到l选k个数的所有可能组合
public static void f1(int i,int l ,int k,int j,int [] arr){
	if(j==k){
		f2(arr,0);
	}
	else
	{	
	for(;i<=l;i++){
		arr[j]=i;
		j++;i++;
		f1(i, l,k,j,arr);
		j--;i--;
	}
	}
}
//排出每不同的5个数的所有排列顺序
private static void f2(int[] s, int k) {
	  if(k==s.length){  
		  if((s[2]*100+s[3]*10+s[4])*(s[1]+s[0]*10)==(s[0]*100+s[3]*10+s[1])*(s[2]*10+s[4])){
				max++; 
			}
	  }		  
	  for(int i=k;i<s.length;i++){
		  int temp=s[k]; s[k]=s[i]; s[i]=temp;
		  f2(s, k+1);
		  temp=s[k]; s[k]=s[i]; s[i]=temp;
	  }
	}
}

方法二:当然也有暴力解法 带过一下 ,这里主要总结了一下递归思想

//方法二
//暴力解法
public static void f3(){
	int count = 0;
    for (int a = 1; a < 10; a++) {
        for (int b = 1; b < 10; b++) {
            if (b != a) for (int c = 1; c < 10; c++) {
                if (c != a && c != b) for (int d = 1; d < 10; d++) {
                    if (d != a && d != b && d != c) for (int e = 1; e < 10; e++) {
                        if (e != a && e != b && e != c && e != d) {
                            if ((a * 10 + b) * (c * 100 + d * 10 + e) == (a * 100 + d * 10 + b) * (c * 10 + e)) {
                                count++;
                            }
                        }
                    }
                }
            }

        }
    }
    System.out.println(count);//142

}

【总结】
有时候想不出来换一种思维来做,看作整体!看作整体!这样就会恍然大悟,并且不会纠结算法到底怎么写的,要不要套一下函数代码来看看,在此过程也要注意变量的问题。
上面是我的个人总结和看法,如有不当之处希望大佬指出,也希望对在学递归的同学有帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值