解决两个字符串的动态规划问题,一般都是用两个指针 i,j 分别指向两个字符串的最后,然后一步步往前走,缩小问题的规模。
1.递归
base case 是 i 走完 s1 或 j 走完 s2,可以直接返回另一个字符串剩下的长度。
对于每对字符 s1[i] 和 s2[j],可以有四种操作:
1 | if s1[i] == s2[j]: |
⏬⏬⏬
1 | public int minDistance(String word1, String word2) { |
这段代码有点小问题就是,这个解法是暴力解法,存在重叠子问题,需要用动态规划技巧来优化。
对于子问题 dp(i-1, j-1),如何通过原问题 dp(i, j) 得到呢?有不止一条路径,比如 dp(i, j) -> #1 和 dp(i, j) -> #2 -> #3。一旦发现一条重复路径,就说明存在巨量重复路径,也就是重叠子问题。
2.动态规划优化
常用就是用HashMap来做备忘录,避免重叠路径:
1 | HashMap<String, Integer> map = new HashMap<>(); |
或是用dp数组:

dp[..][0] 和 dp[0][..] 对应 base case,dp[i][j] 的含义和之前的 dp 函数类似:
1 | int dp(i, j) |
dp 函数的 base case 是 i,j 等于 -1,而数组索引至少是 0,所以 dp 数组会偏移一位。
既然 dp 数组和递归 dp 函数含义一样,也就可以直接套用之前的思路写代码,唯一不同的是,DP table 是自底向上求解,递归解法是自顶向下求解:
1 | int minDistance(String s1, String s2) { |