目 录:
题目5:母牛每年生一只母牛,新出生的母牛成长三年后也能每年生一只母牛,假设不会死。求N年后,母牛的数量
题目2:(背包问题)从数组任意选择数字,能不能累加得到 aim
一、递归
-
暴力递归的步骤:
- 1:把问题转化为规模缩小了的同类问题的子问题;
- 2:有明确的不需要继续进行递归的条件(base case);
- 3:有得到了子问题的结果之后的决策过程;
- 4:不记录每一个子问题的解。
递归其实就是不断的尝试,不知道明确的计算方式,但是明白怎么去试。
题目1:求 n! 的结果
用递归去求解时:很明显求解 n! 其实就是求解 (n - 1)! 的问题,即它的子问题.....
package com.offer.foundation.class6;
/**
* @author pengcheng
* @date 2019/3/30 - 21:27
* @content: n! 问题
*/
public class Factorial {
// 非递归版本
public long getFactorial1(int n){
long res = 1L;
for (int i = 1; i <= n; i++) {
res *= i;
}
return res;
}
// 递归版本
public long getFactorial2(int n){
if(n == 1){
return 1L;
}
return (long) n * getFactorial2(n - 1);
}
// 测试
public static void main(String[] args) {
Factorial factorial = new Factorial();
System.out.println(factorial.getFactorial1(5)); // 120
System.out.println(factorial.getFactorial2(5)); // 120
}
}
题目2:汉诺塔问题
- 打印 n 层汉诺塔从最左边移动到最右边的全部过程:
题目:在一根柱子上从下往上按照大小顺序摞着 n 片黄金圆盘。把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。打印出移动次数最少的全过程。
- 【分析】:给三根柱子分别命名为 “left”、“mid”、“right”,from 代表此次需要移动的圆盘所在的位置,to 代表这些圆盘要去的地方,help 是用于辅助的,分三步走:
- 1、n-1 个圆盘从 from 到 help;
- 2、第 n 个圆盘从 from 到 to;
- 3、把那 n-1个圆盘从 help 移动到 to 上面来。
- 时间复杂度:f(n) = 2f(n-1) +1,是2(n-1)
把尝试的能力写成代码就是递归的过程。
package com.offer.foundation.class6;
/**
* @author pengcheng
* @date 2019/3/30 - 22:18
* @content: 汉诺塔问题
*/
public class Hanoi {
public void hanoi(int n){
if(n > 0){
hanoi(n, "left", "right", "mid");
}
}
/**
* @param n :n个数
* @param from :原位置
* @param help :辅助位置
* @param to : 目标位置
*/
public void hanoi(int n, String from, String to, String help){
if(n == 1){
// 只有一个时,直接移到目标位置即可