LeetCode做题笔记 - 70 - 爬楼梯(简单)
题目:爬楼梯(难度:简单)
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Note: Given n will be a positive integer.
Example 1:
Input: 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps
Example 2:
Input: 3
Output: 3
Explanation: There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step
思路
爬到第N层有2种情况,一是从第N-1层跨一步到第N层,二是从第N-2层跨两步到第N层。所以到第N层的方法数等于到第N-1层和到第N-2层方法数之和。我们用f(N)表示到第N层的方法数,则有 f(N) = f(N-1) + f(N-2)。是不是很像斐波那契数列。
首先想到用递归,但是考虑到复杂度问题,用一个带unordered_map记录已经算得的结果,避免重复运算,时间和空间复杂度都是O(N)。
第二种写法更简单,把f(N)看成一个数组f的第N个元素,那么从0循环到N即可算出f(N),时间和空间复杂度都是O(N)。
虽然理论上两种方法的时间和空间复杂度的数量级一样,但是第二种更省时间和空间,因为递归涉及频繁函数调用消耗时间,而且unordered_map的搜索只是平均为常数时间,最差情况仍与大小有关。
代码
递归
class Solution {
public:
int climbStairs(int n) {
// 递归
if (n == 1) return 1;
if (n == 2) return 2;
if (record.find(n) != record.end()) return record[n]; // 去记录中找结果,避免重复运算
int ways = climbStairs(n-1)+climbStairs(n-2); // 递归调用
record[n] = ways; // 记录结果
return ways;
}
unordered_map<int, int> record; // 记录算过的结果,避免重复运算
};
数组(推荐)
class Solution {
public:
int climbStairs(int n) {
int size = n < 2 ? 3 : n+1; // 确定数组的大小,长度不能小于3
int *sum = new int [size];
sum[0] = 0; // 初始化最开头的元素
sum[1] = 1;
sum[2] = 2;
for(int i = 3; i <= n; i++)
sum[i] = sum[i - 1] + sum[i - 2]; // 根据规则计算
return sum[n];
}
};

浙公网安备 33010602011771号