Day38 动态规划 LeetCode 509 70 746

37 阅读1分钟

Day38 动态规划 LeetCode 509 70 746

理论基础

常见类型

  • 基础题型
  • 背包问题
  • 打家劫舍
  • 股票问题
  • 子序列问题

五部曲

  • DP数组及下标含义
  • 递推公式
  • DP数组初始化
  • 遍历顺序
  • 打印DP数组

509. 斐波那契数

心得

  • 简单入门
  • AC

题解

class Solution {
public:
    int fib(int n) {
        if (n <= 0) return n;
        vector<int> dp(n + 1);
        dp[0] = 0;
        dp[1] = 1;
        for (int i = 2; i < n + 1; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
};

// 只要记录两个状态即可,可以降低O(N)到O(1)
class Solution {
public:
    int fib(int n) {
        if (n <= 0) return n;
        vector<int> dp(2);
        dp[0] = 0;
        dp[1] = 1;
        for (int i = 2; i < n + 1; i++) {
            int sum = dp[0] + dp[1];
            dp[0] = dp[1];
            dp[1] = sum;
        }
        return dp[1];
    }
};

70. 爬楼梯

心得

  • 类似fibonacci那题,推出递归方程即可

题解

class Solution {
public:
    int climbStairs(int n) {
        if (n <= 2) return n;
        vector<int> dp(3);
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) {
            int sum = dp[0] + dp[1];
            dp[1] = dp[1];
            dp[2] = sum;
        }
        return dp[1];
    }
};

746. 使用最小花费爬楼梯

心得

  • 题目含义没完全理解

题解

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        vector<int> dp(cost.size() + 1); // 1. d[i] 爬到第i个台阶所需的最小花费
        dp[0] = 0; // 3. 初始化
        dp[1] = 0;
        for (int i = 2; i < cost.size() + 1; i++) {
            dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]); // 2. 递推公式
        }
        return dp[cost.size()];
    }
};

// 同样只是记录前两个状态,可以优化空间复杂度
class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int dp0 = 0;
        int dp1 = 0;
        for (int i = 2; i <= cost.size(); i++) {
            int dpi = min(dp1 + cost[i - 1], dp0 + cost[i - 2]);
            dp0 = dp1; // 记录一下前两位
            dp1 = dpi;
        }
        return dp1;
    }
};