[LeetCode] Interleaving String

(Version 0.0)

Interleaving String这道题是一道典型的DP题目,思路就是最基本的利用前一个subproblem(substring)的解加上对当前char的判断来解决当前问题的典型的sequence DP问题。我们要考虑的一般性的子问题是:取s1.substring(i)和s2.substring(j),能否interleave成s3.substring(i + j)。如果s1.substring(i)和s2.substring(j)想要interleave成s3.substring(i + j),那么s1.substring(i)和s2.substring(j)中必有至少一个和s3.substring(i + j)有相同的最后一个char,所以易得状态转移关系:若取s1.charAt(i - 1)和s3.charAt(i + j - 1)匹配,则s1.substring(i - 1)和s2.substring(j)必须一起解决掉s3.substring(i + j - 1),即dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i + j - 1);或者若去s2.charAt(j - 1)和s3.charAt(i + j - 1)匹配,则s1.substring(i)和s2.substring(j - 1)必须一起解决掉s3.substring(i + j - 1),即dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1)。代码如下:

 1 public class Solution {
 2     public boolean isInterleave(String s1, String s2, String s3) {
 3         if (s1.length() + s2.length() != s3.length()) {
 4             return false;
 5         }
 6         boolean[][] dp = new boolean[s1.length() + 1][s2.length() + 1];
 7         dp[0][0] = true;
 8         for (int i = 1; i <= s2.length(); i++) {
 9             if (dp[0][i - 1] && s3.charAt(i - 1) == s2.charAt(i - 1)) {
10                 dp[0][i] = true;
11             } else {
12                 break;
13             }
14         }
15         for (int i = 1; i <= s1.length(); i++) {
16             if (dp[i - 1][0] && s3.charAt(i - 1) == s1.charAt(i - 1)) {
17                 dp[i][0] = true;
18             } else {
19                 break;
20             }
21         }
22         for (int i = 1; i <= s1.length(); i++) {
23             for (int j = 1; j <= s2.length(); j++) {
24                 char c = s3.charAt(i + j - 1);
25                 dp[i][j] = dp[i][j - 1] && s2.charAt(j - 1) == c || dp[i - 1][j] && s1.charAt(i - 1) == c;
26             }
27         }
28         return dp[s1.length()][s2.length()];
29     }
30 }

总体来说只要掌握了CLRS或者其他教科书上面的sequence DP的例子,就会发现这题其实换汤不换药,可以套用典型的DP模式。

原文地址:https://www.cnblogs.com/icecreamdeqinw/p/4331424.html