Interleaving String

描述

Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.

For example, Given: s1 = "aabcc", s2 = "dbbca",

When s3 = "aadbbcbcac", return true.

When s3 = "aadbbbaccc", return false.

分析

设状态f[i][j],表示s1[0,i]s2[0,j],匹配s3[0, i+j]。如果s1的最后一个字符等于s3的最后一个字符,则f[i][j]=f[i-1][j];如果s2的最后一个字符等于s3的最后一个字符,则f[i][j]=f[i][j-1]。因此状态转移方程如下:

  1. f[i][j] = (s1[i - 1] == s3 [i + j - 1] && f[i - 1][j])
  2. || (s2[j - 1] == s3 [i + j - 1] && f[i][j - 1]);

递归

  1. // Interleaving String
  2. // 递归,会超时,仅用来帮助理解
  3. public class Solution {
  4. public boolean isInterleave(String s1, String s2, String s3) {
  5. if (s3.length() != s1.length() + s2.length())
  6. return false;
  7. if (s1.isEmpty() || s2.isEmpty()) return true;
  8. return isInterleave(s1, 0, s1.length(),
  9. s2, 0, s2.length(), s3, 0, s3.length());
  10. }
  11. private static boolean isInterleave(String s1, int begin1, int end1,
  12. String s2, int begin2, int end2,
  13. String s3, int begin3, int end3) {
  14. if (begin3 == end3)
  15. return begin1 == end1 && begin2 == end2;
  16. return (begin1 < end1 && s1.charAt(begin1) == s3.charAt(begin3) &&
  17. isInterleave(s1, begin1 + 1, end1, s2, begin2, end2,
  18. s3, begin3 + 1, end3)) ||
  19. (begin2 < end2 && s2.charAt(begin2) == s3.charAt(begin3) &&
  20. isInterleave(s1, begin1, end1,
  21. s2, begin2 + 1, end2, s3, begin3 + 1, end3));
  22. }
  23. }

动规

  1. // Interleaving String
  2. // 二维动规,时间复杂度O(n^2),空间复杂度O(n^2)
  3. public class Solution {
  4. public boolean isInterleave(String s1, String s2, String s3) {
  5. if (s3.length() != s1.length() + s2.length())
  6. return false;
  7. boolean[][] f = new boolean[s1.length() + 1][s2.length() + 1];
  8. for (int i = 0; i < s1.length() + 1; ++i)
  9. Arrays.fill(f[i], true);
  10. for (int i = 1; i

动规+滚动数组

  1. // Interleaving String
  2. // 二维动规+滚动数组,时间复杂度O(n^2),空间复杂度O(n)
  3. public class Solution {
  4. public boolean isInterleave(String s1, String s2, String s3) {
  5. if (s1.length() + s2.length() != s3.length())
  6. return false;
  7. if (s1.length() < s2.length())
  8. return isInterleave(s2, s1, s3);
  9. boolean[] f = new boolean[s2.length() + 1];
  10. Arrays.fill(f, true);
  11. for (int i = 1; i

原文: https://soulmachine.gitbooks.io/algorithm-essentials/content/java/dp/interleaving-string.html