题意:

image.png

解题思路:

  1. 1. 状态定义:dp[i][j]表示s1的前i个字符和s2的前j个字符是否能构成s3的前i+j个字符;
  2. 2. 初始化条件:dp[0][0] = true, s1,s2,s3的长度分别为len1,len2,len3
  3. 3. 初始化第一列dp[i][0],遍历第一列,遍历区间[1,len1+1];
  4. dp[i][0] = dp[i - 1][0] && s1[i - 1] == s3[i - 1]:
  5. 表示s1的前i位是否能构成s3的前i位,因此需要满足的条件为,前i1位可以构成s3的前i1位且s1的第i s1[i1])等于s3的第i位(s3[i1])
  6. 好比 s1:ab[0,1] => s3:acbd[0,1,2,3]=>
  7. (dp[0][0] && s1[0] == s3[0]) => dp[1][0] => true
  8. 4. 初始化第一行dp[0][j],遍历第一行,遍历区间[1,len2+1]:
  9. dp[0][i]=dp[0][i1] && s2[i1]==s3[i1]。
  10. 表示s2的前i位是否能构成s3的前i位。因此需要满足的条件为,
  11. i1位可以构成s3的前i1位且s2的第i位(s2[i-1])等于s3的第i位(s3[i-1])
  12. 5. 遍历dp数组,每一行i,遍历区间[1,len1+1]:
  13. 每一列j,遍历区间[1,len2+1]
  14. dp[i][j] = (dp[i - 1][j] && s1[i - 1] == s3[i - 1 + j])
  15. || (dp[i][j - 1] && s2[j - 1] == s3[j - 1 + i]);
  16. 解释:$s1i位和s2的前j位能否组成s3的前i+j位取决于两种情况:
  17. s1的前i个字符和s2的前j1个字符能否构成s3的前i+j1位,
  18. s2的第j位(s2[j1])是否等于s3的第i+j位(s3[i+j1])
  19. 举例说明:
  20. s1 = 'ab' s2 = 'cd' s3 = 'acbd' =》dp[i][j - 1]=》
  21. 如果s1的第一个字符a等于s3的第一个字符a,那么只需要判断s2j-1个字符c是否等于s3j-1+i个字符
  22. i,j=1的时候s2[j-1] = c, s3[j-i+1] = c,
  23. 所以dp[1][1] = true : 表示s1a s2c能构成s3i+j-1位字符ac

图示:

image.png

PHP代码实现:

  1. class Solution {
  2. /**
  3. * @param String $s1
  4. * @param String $s2
  5. * @param String $s3
  6. * @return Boolean
  7. */
  8. function isInterleave($s1, $s2, $s3) {
  9. $m = strlen($s1);
  10. $n = strlen($s2);
  11. if ($m + $n != strlen($s3)) return false;
  12. $dp = [];
  13. $dp[0][0] = true;
  14. for ($i = 1; $i <= $m; $i++) {
  15. $dp[$i][0] = $dp[$i - 1][0] && $s1[$i - 1] == $s3[$i - 1];
  16. }
  17. for ($i = 1; $i <= $n; $i++) {
  18. $dp[0][$i] = $dp[0][$i - 1] && $s2[$i - 1] == $s3[$i - 1];
  19. }
  20. for ($i = 1; $i <= $m; $i++) {
  21. for ($j = 1; $j <= $n; $j++) {
  22. $dp[$i][$j] = ($dp[$i - 1][$j] && $s1[$i - 1] == $s3[$i - 1 + $j])
  23. || ($dp[$i][$j - 1] && $s2[$j - 1] == $s3[$j - 1 + $i]);
  24. }
  25. }
  26. return $dp[$m][$n];
  27. }
  28. }

GO代码实现:

  1. func isInterleave(s1 string, s2 string, s3 string) bool {
  2. m, n, n3 := len(s1), len(s2), len(s3)
  3. if m + n != n3 {
  4. return false
  5. }
  6. dp := make([][]bool, m+1)
  7. for i := range dp {
  8. dp[i] = make([]bool, n+1)
  9. }
  10. dp[0][0] = true
  11. for i := 1; i <= m; i++ {
  12. dp[i][0] = dp[i-1][0] && (s1[i-1] == s3[i-1])
  13. }
  14. for j := 1; j <= n; j++ {
  15. dp[0][j] = dp[0][j-1] && (s2[j-1] == s3[j-1])
  16. }
  17. for i := 1; i <= m; i++ {
  18. for j := 1; j <= n; j++ {
  19. dp[i][j] = (dp[i-1][j] && s1[i-1] == s3[i+j-1]) ||
  20. (dp[i][j-1] && s2[j-1] == s3[i+j-1])
  21. }
  22. }
  23. return dp[m][n]
  24. }