题目分析:
假设走n级阶梯的计算函数为f(n),走n级阶梯,第一步两种走法,走1级或走2级;
两种走法相应地剩下一定数量的阶梯,他们对应的走法分别是f(n-1), f(n-2);
f(n)=f(n-1)+f(n-2),得到递推公式;
初始状态1级,2级阶梯对应的走法分别是1和2,即f(1)=1, f(2)=2;
结合递推公式可计算得到f(3), f(4), f(5)...f(n)...任意数量阶梯的走法。
代码思路:
1.递归算法
*直接调用递归方法
class Solution{
public int climbStairs(int n){
if(n==1)return 1;//初始状态直接输出
if(n==2)return 2;
return climbStairs(n-1)+climbStairs(n-2);//n>3调用自己递推计算
}
}
优点:代码书写简单
缺:假设求f(n),f(n)=f(n-1)+f(n-2),f(n-1)=f(n-2)+f(n-3),f(n-2)=f(n-3)+f(n-4),f(n-3)=...,f(n-4)=...,...=f(2)+f(1),每个值都用递归单独计算一次,产生了非常多的重复计算,时间复杂度为O(n^2),效率比较低,因此考虑使用*HashMap。
定义一个HashMap,每次计算前先从Hash表中获取,获取不到再用递归算法求解,求解出来的值放入HashMap中方便下次使用,时间复杂度是O(m),属于线性时间复杂度。
代码:
class Solution{
private Map<Integer,Integer> storeMap=new HashMap<>();
public int climbStairs(int n){
if(n==1)return 1;
if(n==2)return 2;
if(null!=storeMap.get(n))//括号应为英文括号
return storeMap.get(n);
else{
int result=climbStairs(n-1)+climbStairs(n-2);
storeMap.put(n,result);//HashMap的参数成对出现
return result;
}
}
}
总结:
分3种情况
n为初始状态,直接输出走法数;
n在Hash表中,获取走法数然后输出;
n不在Hash表中,递归计算得到走法数,存入Hash表,返回值;
2.循环算法
递归算法的思路是从最终应求结果,往回考虑n-1项,最终追溯到f(1)和f(2),再自下而上,递推得到最终结果。循环算法自下而上计算每种情况的走法数,直到阶梯数量与题目要求的相同,即得到答案。计算n级阶梯的方法数f(n)总是会用到f(n-1)和f(n-2),因此,在由下而上的计算过程中,要用2个参数,实时记录这两个值。
代码:
class Solution{
public int climbStairs(int n){
if(n==1)return 1;//标点用英文
if(n==2)return 2;
int pre=2;
int prePre=1;
for(int i=3;;i++){//i为阶梯数/先计算还是先判断,先计算,因为不管阶梯数是多少,后面要么输出,
int result=pre+prePre; //要么作为pre/prePre,都会用到,判断不是判断是否计算,而是判断是否输出
if(n==i)return result;//先判断再赋值,如果是要求的阶梯数,就不必再计算下个计算目标的递推数
prePre=pre;
pre=result;
}
}
}
*斐波那契数列解法同理
声明:内容学习自b站视频"【比刷剧还爽!】13天高效刷题 | 哔哩最强LeetCode算法刷题...",感谢up,获益良多。文字全部是个人学习总结,代码为个人默打,如有侵权,请联系后处理。