97. Interleaving String
问题:
给定3个字符串,
由s1和s2构成s3。
若可以做到,返回true,否则返回false。
Example 1: Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac" Output: true Example 2: Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc" Output: false Example 3: Input: s1 = "", s2 = "", s3 = "" Output: true Constraints: 0 <= s1.length, s2.length <= 100 0 <= s3.length <= 200 s1, s2, and s3 consist of lowercase English letters.
example 1:
解法:DP
⚠️ 注意:本问题中,s1分成的n个子串,和s2分成的m个子串,
要求:|n-m|<1
其实,从s1中每次选一个or多个字符 or 从s2中选一个or多个字符,轮流进行选取,最终一定满足 |n-m|<1
1.状态:
- i:s1的第0~i个字符
- j:s2的第0~j个字符
2.选择:OR {
s3[i+j]
- ==s1[i]:选s1[i] -> =dp[i-1][j]
- ==s2[j]:选s2[j] -> =dp[i][j-1]
}
3. dp[i][j]:
- 字符串s1选到第i个字符,s2选到第j个字符,是否能构成s3。
4.状态转移方程:
dp[i][j]= OR {
- s3[i+j]==s1[i] && dp[i-1][j]
- s3[i+j]==s2[i] && dp[i][j-1]
}
5.base:
- dp[0][0]=true
- dp[i][0] = s3[j]==s1[i] && dp[i-1][0]
- dp[0][j] = s3[j]==s2[j] && dp[0][j-1]
代码参考:
1 class Solution { 2 public: 3 //dp[i][j][0]: s1[0~i] s2[0~j] 4 //opt: OR : 5 //case_1: + s1[i-1]: 6 // cond: s3[i+j-1]==s1[i-1] 7 // dp[i-1][j] 8 //case_2: + s2[j-1]: 9 // cond: s3[i+j-1]==s2[j-1] 10 // dp[i][j-1] 11 //base: 12 //dp[0][0] = true 13 //dp[0][x] = dp[0][x-1] && s3[x-1]==s2[x-1] 14 //dp[x][0] = dp[x-1][0] && s3[x-1]==s1[x-1] 15 bool isInterleave(string s1, string s2, string s3) { 16 int len1 = s1.length(); 17 int len2 = s2.length(); 18 if(len1+len2!=s3.length()) return false; 19 vector<vector<bool>> dp(len1+1, vector<bool>(len2+1, false)); 20 dp[0][0] = true; 21 for(int i=0; i<=len1; i++) { 22 for(int j=0; j<=len2; j++) { 23 if(i==0 && j==0) dp[i][j] = true; 24 else if(i==0) dp[i][j] = (dp[i][j-1] && s3[j-1]==s2[j-1]); 25 else if(j==0) dp[i][j] = (dp[i-1][j] && s3[i-1]==s1[i-1]); 26 else { 27 dp[i][j] = ((dp[i][j-1] && s3[i+j-1]==s2[j-1]) || 28 (dp[i-1][j] && s3[i+j-1]==s1[i-1])); 29 } 30 } 31 } 32 return dp[len1][len2]; 33 } 34 };