70、爬楼梯
描述:假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
解法1:采用递归实现,不过在力扣中提交超时了。
思路:找到程序的出口,即f(n) = f(n-1)+f(n-2)。但是递归中有很多重复的计算,还需要优化。
解释,比如有5阶楼梯,需要我们求爬到5阶能有多少种次数?因为一次只能爬一阶或者两阶所以说爬到5阶爬法就是爬到4阶的方法次数加上爬到3阶方法的次数。因为:我们从3阶可以直接到5阶,从4阶也可以直接到5阶,例如爬到3阶有123,13,23三种方法,爬到4阶有1234,124,134,23,234五种方法,所以到5阶有8种方法。即是,我可以选择到3层后在到5层,也可以 选择到4层后在到5层。所以到5层的方法就是到4层的方法次数加上到3层的方法次数。即f(a) = f(a-1)+f(a-2)
初步想法是,通过一个list记录已经计算过的值。
class Solution { public int climbStairs(int n) { if(n==1){ return 1; }else if(n==2){ return 2; }else{ return climbStairs(n-1)+climbStairs(n-2); } } }
解法2: 对动态规划重复计算的优化,采用一个list记录之前方法的次数。
class Solution { public int climbStairs(int n) { List<Integer> list = new ArrayList<Integer>(); //先记录1阶和2阶的次数,先增加0是为了让索引与n对应 list.add(0); list.add(1); list.add(2); //用list记录到达第n阶的方法次数 for(int i =3;i<=n;i++){ list.add(list.get(i-1)+list.get(i-2)); } //list的最后一个元素就是到达第n阶方法的次数。 return list.get(n); } }
解法3:数学表达式为f(a) = f(a-1)+f(a-2).当前要求的数是前面两个数的和。动态规划题
其实就是斐波那契数列。此方法和方法1一个思路,只不过记录前两个次数没采用数组的形式。
执行用时: 3 ms, 在Climbing Stairs的Java提交中击败了82.31% 的用户
class Solution { public int climbStairs(int n) { int a =0; int b =1; int result=0; for(int i=1;i<=n;i++){ result=a+b; a=b; b=result; } return result; } }