题目链接:https://leetcode-cn.com/problems/climbing-stairs/
题目描述:
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
示例 2:
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
设f(n)是上n个台阶的可能性数,可以考虑最后一步分为上1个台阶或上2个台阶,这样就可以得到
f(n)=f(n-1)+f(n-2)
我们从0开始计算,由0台阶上0个台阶,f(0)=0;
由0台阶上1个台阶,f(1)=1;
这样,我们就可以由这两项得到f(2),f(3),……f(n)。
解法一
我们可以在计算过程中使用数组保存过程中的每一个结果。
class Solution {
public int climbStairs(int n) {
if(n==1) return 1;
int[] array=new int[n];
array[0]=1;
array[1]=2;
for(int i=2;i<n;i++){
array[i]=array[i-1]+array[i-2];
}
return array[n-1];
}
}
时间复杂度为O(n),空间复杂度为O(n)
解法二
也可以只使用三个变量来保存需要的最近的三个值,即f(n),f(n-1)和f(n-2)。
class Solution {
public int climbStairs(int n) {
int p=0,q=0,r=1;
for(int i=1;i<=n;i++){
p=q;
q=r;
r=p+q;
}
return r;
}
}
时间复杂度为O(n),空间复杂度为O(1)
解法三
我们可以看到,这个问题其实就是求斐波那契数列,斐波那契数列的通项公式为:
可以直接由通项公式得到结果。
同时由于本题目中不包含斐波那契数列的第1项f(0),所以我们实际要求的是第n+1项,即f(n+1)。
class Solution {
public int climbStairs(int n) {
double s=Math.sqrt(5);
double fib=Math.pow((1+s)/2,n+1)-Math.pow((1-s)/2,n+1);
return (int)(fib/s);
}
}
时间复杂度为O(logn),因为pow()操作的时间复杂度为O(logn)。
空间复杂度为O(1)。