70. 爬楼梯

70. 爬楼梯 - 力扣(LeetCode)

class Solution {
  vector<int> DP{0, 1, 2};
public:
  int climbStairs(int n) {
    DP.reserve(n + 1);

    for (int i = 3; i <= n; ++i)
      DP[i] = DP[i - 1] + DP[i - 2];

    return DP[n];
  }
};

事实上这道题只需要考虑到 i - 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;
    }
};

其实这就是斐波那契数列。

二刷

class Solution {
public:
  int climbStairs(int n) {
    vector<int> PossibleWays(50);
    PossibleWays[0] = 1; // Already at the top.
    PossibleWays[1] = 1; // Only one way (+1) to the top.

    // Continue calculating the remaining possibilities. Keep in mind that the
    // analogy is thinking BACKWARDS instead of forwards.
    for (int i = 2; i <= n; ++i)
      // [i - 1] means +1 to n; [i - 2] means +2 to n.
      PossibleWays[i] = PossibleWays[i - 1] + PossibleWays[i - 2];

    return PossibleWays[n];
  }
};

无脑DP确实爽,我操。注意这里的analogy画出来图的话就是这样:

Pasted image 20260906113447.png

你可以观察到,我们是从\(n\)往下看,而不是思考向上怎么走到\(n\)。这是非常重要的思维方式的特点。