动态规划面试题精选

2025年 阅读约 13 分钟 面试指南 · 算法面试

精选动态规划面试高频题目,涵盖背包问题、子序列问题、路径问题等,附状态转移方程和解题模板。

一句话总结

动态规划是算法面试的难点,核心考点:三要素(最优子结构+重叠子问题+状态转移方程)、背包问题(0-1背包逆序 vs 完全背包正序)、子序列(LIS/LCS)、路径问题(网格DP)。解题步骤:定义dp含义→推导转移方程→确定初始条件→举例验证。

动态规划核心思想

动态规划三要素:

1. 最优子结构:大问题的最优解包含小问题的最优解。

2. 重叠子问题:递归过程中会重复计算相同的子问题。

3. 状态转移方程:描述大问题和小问题之间的关系。

解题步骤:
1. 定义dp数组含义
2. 推导状态转移方程
3. 确定初始条件和遍历顺序
4. 举例验证

背包问题

0-1背包:每个物品只能选一次。

dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])

空间优化:一维数组逆序遍历。

完全背包:每个物品可以选多次。

dp[i][j] = max(dp[i-1][j], dp[i][j-w[i]] + v[i])

空间优化:一维数组正序遍历。

面试变体:零钱兑换、分割等和子集、目标和。

子序列问题

最长递增子序列(LIS):

dp[i]表示以nums[i]结尾的LIS长度,dp[i] = max(dp[j] + 1) for j < i and nums[j] < nums[i]。时间O(n²),贪心+二分优化到O(nlogn)。

最长公共子序列(LCS):

dp[i][j]表示text1前i个和text2前j个的LCS长度。

若text1[i-1]==text2[j-1]:dp[i][j]=dp[i-1][j-1]+1
否则:dp[i][j]=max(dp[i-1][j], dp[i][j-1])

路径问题

不同路径:从左上角到右下角有多少条路径。

dp[i][j] = dp[i-1][j] + dp[i][j-1],障碍物位置为0。

最小路径和:dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]

三角形最小路径和:自底向上dp[i][j] = min(dp[i+1][j], dp[i+1][j+1]) + triangle[i][j]

实战场景

场景:0-1背包(面试高频模板)

// 0-1背包:容量W,N个物品,重量wt[],价值val[] // dp[i][w] = max(dp[i-1][w], dp[i-1][w-wt[i]] + val[i]) // 空间优化:一维数组逆序遍历 public int knapsack(int W, int[] wt, int[] val) { int[] dp = new int[W + 1]; for (int i = 0; i < wt.length; i++) { for (int w = W; w >= wt[i]; w--) { // 逆序! dp[w] = Math.max(dp[w], dp[w - wt[i]] + val[i]); } } return dp[W]; } // 完全背包:正序遍历即可 // for (int w = wt[i]; w <= W; w++) { ... } // 面试变体:零钱兑换、分割等和子集、目标和