本文简述动态规划的思想及常见经典面试题:
动态规划(Dynamic Programming)简称DP,是一般算法中最灵活多变的一种。因为其只是一种思想,但实现方式有很多种,基于特定的实现方式各整出五花八门的题目。
但核心思想就几句话:
- 找状态转移方程
- 问题具有最优子结构
- 重叠子问题
其中最灵活多变的就是要找出合适的状态转移方程了。其中还要注意的是dp数组的定义,因为数组的定义决定了状态转移方程的定义,小猪亲自试了力扣上面的很多动态规划的题目,在没有熟悉其固定套路之前确实很难想到对应的解法。
只有多多联系,多多思考总结讨论,才能在遇到类似题目时手到擒来,相信读者们一定可以。
1、线性 DP
最经典单串:
- 最长上升子序列
1 | public int lengthOfLIS(int[] nums) { |
最经典双串:
- 最长公共子序列
经典问题:
三角形最小路径和
最大子序和
乘积最大子数组
鸡蛋掉落(DP+二分)
俄罗斯套娃信封问题
打家劫舍系列: (打家劫舍3 是树形DP)
打家劫舍
打家劫舍 II
股票系列:
买卖股票的最佳时机
买卖股票的最佳时机 II
买卖股票的最佳时机 III
买卖股票的最佳时机 IV
最佳买卖股票时机含冷冻期
买卖股票的最佳时机含手续费
字符串匹配系列
编辑距离
通配符匹配
正则表达式匹配
2、区间 DP
最长回文子序列
统计不同回文子字符串
多边形三角剖分的最低得分
奇怪的打印机
戳气球
3、背包 DP
分割等和子集 (01背包-要求恰好取到背包容量)
目标和 (01背包-求方案数)
零钱兑换 (完全背包)
零钱兑换 II (完全背包-求方案数)
一和零 (二维费用背包)
4、树形 DP
二叉树中的最大路径和
树的直径 (邻接表上的树形DP)
二叉树的直径
最大 BST 子树
打家劫舍 III
5、状态压缩 DP
我能赢吗
优美的排列
骑士拨号器
参加考试的最大学生数
6、数位 DP
数字 1 的个数
最大为 N 的数字组合
可被 K 整除的最小整数
7、计数型 DP
计数型DP都可以以组合数学的方法写出组合数,然后dp求组合数
不同路径
不同路径 II
不同的二叉搜索树 (卡特兰数)
不相交的握手 (卢卡斯定理求大组合数模质数)
8、递推型 DP
所有线性递推关系都可以用矩阵快速幂做,可以O(logN),最典型是斐波那契数列
爬楼梯
斐波那契数
骑士拨号器
N 天后的牢房
第 N 个泰波那契数
9、概率型 DP
求概率,求数学期望
分汤
新21点
10、博弈型 DP
策梅洛定理,SG 定理,minimax
翻转游戏
翻转游戏
翻转游戏 II
Nim游戏
- Nim 游戏
石子游戏
石子游戏
石子游戏 II
井字游戏
判定井字棋胜负
有效的井字游戏
找出井字棋的获胜者
11、记忆化搜索
本质是 dfs + 记忆化,用在状态的转移方向不确定的情况
矩阵中的最长递增路径
出界的路径数