[LeetCode]Interleaving String

Question

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.


本题难度Hard。

DP

【复杂度】
时间 O(MN) 空间 O(MN)

【题意】
开始我搞不清题目意思,还以为是分别从s1和s2中交错有规律的选取字符生成s3,实际上就是从左往右任意地从s1与s2分别选取字符,极端情况就是先取完s1的,再取s2的。

【思路】
[LeetCode]Edit Distance比较相似,不同点在于[LeetCode]Edit Distance是一定能够完成的,而这里却要根据上一步和这一步的情况加以判断。

f[i][j]代表分别从s1中选取了i个字符和s2中选取了j个字符后,所生成的字串能否等于s3从0到i+j-1这段的子串。可以看出来有两个途径能到达f[i][j]

  1. f[i-1][j]f[i][j]。如果f[i-1][j]==false,说明上步失败了,所以这步也是失败;如果f[i-1][j]==true,这时插入的是s1[i-1],如果s1[i-1]==s3[i+j-1]才能说f[i][j]==true
  2. f[i][j-1]f[i][j]。如果f[i][j-1]==false,说明上步失败了,所以这步也是失败;如果f[i][j-1]==true,这时插入的是s2[j-1],如果s2[j-1]==s3[i+j-1]才能说f[i][j]==true

由上面可得出状态转移方程:

这里写图片描述

【附】
DP矩阵可以用boolean矩阵。

【注意】
记得设置 f[0][0]=true;

【代码】

public class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        //require
        int m=s1.length(),n=s2.length();
        if(s3.length()!=m+n)
            return false;
        boolean[][] f=new boolean[m+1][n+1];
        f[0][0]=true;
        for(int i=1;i<m+1;i++)
            f[i][0]=f[i-1][0]&&s1.charAt(i-1)==s3.charAt(i-1);
        for(int i=1;i<n+1;i++)
            f[0][i]=f[0][i-1]&&s2.charAt(i-1)==s3.charAt(i-1);
        //invariant
        for(int i=1;i<m+1;i++)
            for(int j=1;j<n+1;j++)
                f[i][j]=(f[i-1][j]&&s1.charAt(i-1)==s3.charAt(i+j-1))||
                        f[i][j-1]&&s2.charAt(j-1)==s3.charAt(i+j-1);
        //ensure
        return f[m][n];
    }
}

参考

leetCode 97.Interleaving String (交错字符串) 答题思路和方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值