#97 Interleaving String

Description

Given strings s1, s2, 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.

Examples

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.

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

思路

  • 最原始的思路就是递归了呀,设定一下终止条件(顺便剪下枝),然后一个一个char比较就可以了,但很明显,这个方法会导致TLE(代码附上了,不死心还是submit了一下)

  • 正常做法应该就是dp了,这次用的是二维的dp,最开始想了很久,虽然把表格弄出来了,但是更新规则还是不清楚,去看了lc的solution,发现忘记了重要的一条:

    • 如果 s1.substring(0, i) 和 s2.substring(0, j) 能构成 s3.substring(0, k),那么 k = i + j - 1
    • 写成上面的形式是多么显而易见的事情啊,有了这个前提之后就可以构建2D表格了
  • 以s1 = ddda, s2 = da, s3 = ddadda为例

初始dp表格如下

-0ddda
0
d
a

更新dp第0行和第0列

-0ddda
0Tdp[0][0]=T && s1[0]=s3[0+1-1] (T)dp[0][1]=T && s1[1]=s3[0+2-1] (T)dp[0][2]=T && s1[2]!=s3[0+3-1] (F)dp[0][3]=F (F)
ddp[0][0]=T & s2[0]=s3[1+0-1] (T)
adp[1][0]=T & s2[1]!=s3[2+0-1] (F)

根据更新公式:
d p [ i ] [ j ] = ( d p [ i − 1 ] [ j ]    & &    s 1 [ i − 1 ] = = s 3 [ i + j − 1 ] )    ∣ ∣    ( d p [ i ] [ j − 1 ]    & &    s 2 [ j − 1 ] = = s 3 [ i + j − 1 ] ) dp[i][j] = (dp[i - 1][j] ~~\&\&~~ s1[i - 1] == s3[i + j - 1])~~ ||~~ (dp[i][j - 1] ~~\&\&~~ s2[j - 1] == s3[i + j - 1]) dp[i][j]=(dp[i1][j]  &&  s1[i1]==s3[i+j1])    (dp[i][j1]  &&  s2[j1]==s3[i+j1])
更新

-0ddda
0TTTFF
dT左边的T&上面的d和s3作比较(T)左边的T&上边的d和s3作比较d!=a / 上边的T&左边的d和s3作比较d!=a(F)左边和上面都是F(F)左边和上边都是F(F)
aF上边的T和左边的a作比较(T)左边的T&上边的d和s3作比较(T)左边的T&上边的d和s3作比较(T)左边的T&上边的a和s3作比较(T)

代码

递归

class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        if (s1.equals("") && s2.equals("") && s3.equals(""))
            return true;
        if (s1.length() + s2.length() != s3.length())
            return false;
        
        if (s1.equals(""))
            return s3.equals(s2);
        if (s2.equals(""))
            return s3.equals(s1);
        
        if (s1.charAt(0) != s3.charAt(0) && s2.charAt(0) != s3.charAt(0))
            return false;
        
        if (s1.charAt(0) != s3.charAt(0))
            return isInterleave(s1, s2.substring(1), s3.substring(1));
        if (s2.charAt(0) != s3.charAt(0))
            return isInterleave(s1.substring(1), s2, s3.substring(1));
        
        return isInterleave(s1, s2.substring(1), s3.substring(1)) || isInterleave(s1.substring(1), s2, s3.substring(1));
    }
}

DP

class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        if (s1.length() + s2.length() != s3.length())
            return false;
        
        boolean dp[][] = new boolean[s1.length() + 1][s2.length() + 1];
        
        dp[0][0] = true;
        for (int i = 1; i < s1.length() + 1; i++)
            dp[i][0] = dp[i - 1][0] && s1.charAt(i - 1) == s3.charAt(i - 1);
        for (int i = 1; i < s2.length() + 1; i++)
            dp[0][i] = dp[0][i - 1] && s2.charAt(i - 1) == s3.charAt(i - 1);
        
        for (int i = 1; i < s1.length() + 1; i++){
            for (int j = 1; j < s2.length() + 1; j++){
                dp[i][j] = (dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i + j - 1)) ||
                    (dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1)); 
            }
        }
        
        return dp[s1.length()][s2.length()];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值