题目

有一座高度是10级台阶的楼梯, 从下往上走, 每跨一步只能向上1级或者2级台阶. 要求用程序来求出一共有多少种走法

 

公式推导

1: ​​[1]​​​ = 1 种
2: ​​​[1,1],[2]​​​ = 2 种
3: ​​​[1,1,1],[1,2],[2,1]​​​ = 3 种
4: ​​​[1,1,1,1],[2,1,1],[1,2,1],[1,1,2],[2,2]​​​ = 5 种
5: ​​​[1,1,1,1,1],[2,1,1,1],[1,2,1,1],[1,1,2,1],[1,1,1,2],[2,2,1],[2,1,2],[1,2,2]​​​ = 8 种

n: ​​​f(n) = f(n - 1) + f(n - 2)​

 

逆向推导

假设楼梯有 n 阶, 则一共有 f(n) 种走法。 假设此时站在第 n 阶往下走

  1. 第一次跨一步只跨1个台阶, 则剩余 n - 1 阶台阶共有 f(n - 1) 种走法
  2. 第一次跨一步只跨2个台阶, 则剩余 n - 2 阶台阶共有 f(n - 2) 种走法

即:​​f(n) = f(n - 1) + f(n - 2)​

 

方式1 - 递归实现

public class AnswerApp {

public static void main(String[] args) {
long startTime = System.currentTimeMillis();

BigDecimal fn = f(100);

System.out.println("fn: " + fn);

long endTime = System.currentTimeMillis();

System.out.println("execute time " + (endTime - startTime) / 1000 + " s.");
}

public static BigDecimal f(int n) {
if (n < 0) {
return new BigDecimal(0);
} else if (n == 1 || n == 2) {
return new BigDecimal(n);
} else {
return f(n - 1).add(f(n - 2));
}
}

}

 

方式2 - 递归+备忘录实现

public class AnswerApp {

public static void main(String[] args) {
long startTime = System.currentTimeMillis();

BigDecimal fn = f(100, new HashMap<>());

System.out.println("fn: " + fn);

long endTime = System.currentTimeMillis();

System.out.println("execute time " + (endTime - startTime) / 1000 + " s.");
}

public static BigDecimal f(int n, HashMap<Integer, BigDecimal> cache) {
if (n < 0) {
return new BigDecimal(0);
} else if (n == 1 || n == 2) {
return new BigDecimal(n);
} else {
if (cache.containsKey(n)) {
return cache.get(n);
}
BigDecimal rlt = f(n - 1, cache).add(f(n - 2, cache));
cache.put(n, rlt);
return rlt;
}
}

}

 

​推荐使用:​递归+备忘录, 原因: 引入缓存,极大的增强了算法的计算效率