[LeetCode] 97. Interleaving String

Given strings s1s2, and s3, find whether s3 is formed by an interleaving of s1 and s2.

An interleaving of two strings s and t is a configuration where they are divided into non-empty substrings such that:

  • s = s1 + s2 + ... + sn
  • t = t1 + t2 + ... + tm
  • |n - m| <= 1
  • The interleaving is s1 + t1 + s2 + t2 + s3 + t3 + ... or t1 + s1 + t2 + s2 + t3 + s3 + ...

Note: a + b is the concatenation of strings a and b.

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
  • s1s2, and s3 consist of lowercase English letters. 

Follow up: Could you solve it using only O(s2.length) additional memory space?

交错字符串。

给定三个字符串 s1、s2、s3,请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。

两个字符串 s 和 t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串:

s = s1 + s2 + ... + sn
t = t1 + t2 + ... + tm
|n - m| <= 1
交错 是 s1 + t1 + s2 + t2 + s3 + t3 + ... 或者 t1 + s1 + t2 + s2 + t3 + s3 + ...
注意:a + b 意味着字符串 a 和 b 连接。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/interleaving-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题意是给 s1, s2 和 s3,验证 s3 是否是由 s1 和 s2 交错组成的。这是典型的二维 DP 题,设 dp[i][j] 是 s1 的前 i 个字符 + s2 的前 j 个字符组成的结果是否能跟 s3 的前 i + j 个字符匹配。首先排除 corner case,如果 s1 + s2 的长度不等于 s3,则说明是不行的。另外,还需要先在二维数组中计算出当 s1 为空和当 s2 为空的时候相对应的 DP 值。最后 normal case 是这两种其中一种为 true 则 dp[i][j] 为 true。

  • s1 的前 i - 1 个字符 + s2 的前 j 个字符
  • s1 的前 i 个字符 + s2 的前 j - 1 个字符

其实也就是 s1 和 s2 拼接出来的部分的最后一个字符可来自于 s1 也可来自于 s2,只要有一种情况为 true 则整体就为 true。这里我还是提供自上而下和自下而上两种实现方式,时间空间复杂度相同。

时间O(mn)

空间O(mn)

DP自上而下

 1 class Solution {
 2     int[][] memo;
 3     
 4     public boolean isInterleave(String s1, String s2, String s3) {
 5         int m = s1.length();
 6         int n = s2.length();
 7         // corner case
 8         if (m + n != s3.length()) {
 9             return false;
10         }
11         
12         // normal case
13         memo = new int[m + 1][n + 1];
14         for (int[] row : memo) {
15             Arrays.fill(row, -1);
16         }
17         return dp(s1, 0, s2, 0, s3);
18     }
19     
20     private boolean dp(String s1, int i, String s2, int j, String s3) {
21         int k = i + j;
22         // base case
23         if (k == s3.length()) {
24             return true;
25         }
26         
27         if (memo[i][j] != -1) {
28             return memo[i][j] == 1 ? true : false;
29         }
30         boolean res = false;
31         if (i < s1.length() && s1.charAt(i) == s3.charAt(k)) {
32             res = dp(s1, i + 1, s2, j, s3);
33         }
34         if (j < s2.length() && s2.charAt(j) == s3.charAt(k)) {
35             res = res || dp(s1, i, s2, j + 1, s3);
36         }
37         memo[i][j] = res == true ? 1 : 0;
38         return res;
39     }
40 }

 

DP自下而上

 1 class Solution {
 2     public boolean isInterleave(String s1, String s2, String s3) {
 3         int m = s1.length();
 4         int n = s2.length();
 5         // corner case
 6         if ((m + n) != s3.length()) {
 7             return false;
 8         }
 9 
10         // normal case
11         boolean[][] dp = new boolean[m + 1][n + 1];
12         dp[0][0] = true;
13 
14         // 考虑当 s2 为空的时候,s1 能组合吗
15         for (int i = 1; i < dp.length; i++) {
16             dp[i][0] = dp[i - 1][0] && (s1.charAt(i - 1) == s3.charAt(i - 1));
17         }
18 
19         // 考虑当 s1 为空的时候,s2 能组合吗
20         for (int i = 1; i < dp[0].length; i++) {
21             dp[0][i] = dp[0][i - 1] && (s2.charAt(i - 1) == s3.charAt(i - 1));
22         }
23 
24         // normal case
25         for (int i = 1; i < dp.length; i++) {
26             for (int j = 1; j < dp[0].length; j++) {
27                 dp[i][j] = (dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i + j - 1))
28                         || (dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1));
29             }
30         }
31         return dp[m][n];
32     }
33 }

 

LeetCode 题目总结

posted @ 2020-05-15 14:24  CNoodle  阅读(475)  评论(0编辑  收藏  举报