动态规划
- 状态定义:
dp[i][j]
表示s1
的前i
个字符和s2
的前j
个字符是否能构成s3
的前i+j
个字符。- 当
i=len1
,j=len2
时,dp[len1][len2]
即为答案。
- 状态转移:分两种情况
- 当
dp[i][j-1]=true
(s1
的前i
个字符和s2
的前j-1
个字符构成s3
的前i+j-1
个字符),且s2[j]==s3[i+j]
(s2
的第j
个字符等于s3
的第i+j
个字符)时,dp[i][j]=true
(s1
的前i
个字符和s2
的前j
个字符构成s3
的前i+j
个字符) - 当
dp[i-1][j]=true
(s1
的前i-1
个字符和s2
的前j
个字符构成s3
的前i+j-1
个字符),且s1[i]==s3[i+j]
(s1
的第i
个字符等于s3
的第i+j
个字符)时,dp[i][j]=true
(s1
的前i
个字符和s2
的前j
个字符构成s3
的前i+j
个字符)
- 当
- 状态初始化:
dp[0][0]=true
,方便后续进行比较,如果设置成了false
,后续比较均为false
(也可以理解为两个空字符)。- 对首行首列进行初始化,以首列为例,相当于
s2
不提供字符,判断s1
的前i
个字符是否能构成s3
的前i
个字符。
注意:下标索引和dp数组索引的差异
class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
int len1 = s1.length(), len2 = s2.length(), len3 = s3.length();
if (len1 + len2 != len3) return false;
boolean[][] dp = new boolean[len1 + 1][len2 + 1];
dp[0][0] = true;
for (int i = 1; i < len1 + 1; ++i) {
dp[i][0] = dp[i - 1][0] && s1.charAt(i - 1) == s3.charAt(i - 1);
}
for (int j = 1; j < len2 + 1; ++j) {
dp[0][j] = dp[0][j - 1] && s2.charAt(j - 1) == s3.charAt(j - 1);
}
for (int i = 1; i < len1 + 1; ++i) {
for (int j = 1; j < len2 + 1; ++j) {
dp[i][j] = (dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1)) ||
(dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i + j - 1));
}
}
return dp[len1][len2];
}
}