动态规划问题汇总(LeetCode)

1,463 阅读2分钟

动态规划算法(Dynamic Programming)是一门非常热门的解决复杂问题的递归算法,一直是面试算法的热点,本文整理并归纳了一些DP思路技巧和对应的LeetCode题目,方便刷题和复习理解。

动态规划是用来求解把多阶段过程问题求解转化为一系列单阶段问题的,它用于求解以阶段划分的动态过程的优化问题,也就是说,动态规划实际上是暴力递归的一种优化,不同的是DP记录了当前动态过程的状态以便之后的状态求解。动态规划常用于多种优化问题,如最短路线、库存管理、资源分配、设备更新、排序、装载等。

我们把DP问题分为多种类型:

  1. 线性DP;
  2. 区间DP;
  3. 背包DP;
  4. 树形DP;
  5. 状态压缩DP;
  6. 数位DP;
  7. 计数型DP;
  8. 递推型DP;
  9. 概率型DP;
  10. 博弈型DP;
  11. 记忆化搜索;

其中我感觉线性DP问题最多,并且其相关思想足以适用于多数DP问题。所以本文归纳了都是线性DP问题。


步骤:

  1. 确定是否能够使用DP
  2. 确定dp[i] / dp[i] [j]代表什么
  3. 确定状态转移方程(重难点)
  4. 获得结果

入门:

  1. 746. Min Cost Climbing Stairs

    for (int i = 2; i < len; ++i) {
                dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];
    }
    
  2. 64. Minimum Path Sum

    for (i = 1; i < m; ++i) {
                for (j = 0; j < n; ++j) {
                    if (j == 0) {
                        dp[j] += grid[i][j];
                    }
                    else {
                        dp[j] = Math.min(dp[j], dp[j - 1]) + grid[i][j];
                    }
                }
            }
    
  3. 198. House Robber

    for (int i = 2; i < len; ++i)
                for (int j = i - 2; j >= 0; --j) 
                    dp[i] = Math.max(dp[i], dp[j] + nums[i]);
    

练习:

300 Longest Increasing Subsequence(最经典单串)

1143 Longest Common Subsequence(最经典双串)

120 Triangle

53 Maximum Subarray

62 Unique Path

70 Climbing Stairs

5 Longest Palindromic Substring

931 Minimum Falling Path Sum

121 Best Time to Buy and Sell Stock

更多分类可以参考:github.com/Woodyiiiiii…


参考资料: