Interleaving String

本文探讨了一个经典的字符串问题:如何判断一个字符串s3是否可以通过交错两个给定字符串s1和s2形成。通过深入分析,文章提供了两种解决方案:一种是递归的深度优先搜索方法,另一种则是更高效的动态规划算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

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.

这个题一开始用的是dfs,超时了:

public class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
		int n1=s1.length(),n2=s2.length(),n3=s3.length();
		if(n1+n2!=n3){
			return false;
		}
		if(n3==0)
			return true;
		int i=n1-1,j=n2-1,k=n3-1;
		if(i>=0&&s1.charAt(i)==s3.charAt(k)&&(j==-1||s2.charAt(j)!=s3.charAt(k))){
			return isInterleave(s1.substring(0,i), s2, s3.substring(0,k));
		}
		if(j>=0&&s2.charAt(j)==s3.charAt(k)&&(i==-1||s1.charAt(i)!=s3.charAt(k))){
			return isInterleave(s1, s2.substring(0,j), s3.substring(0,k));
		}
		if(i>=0&&s1.charAt(i)==s3.charAt(k)&&j>=0&&s2.charAt(j)==s3.charAt(k)){
			return isInterleave(s1.substring(0,i), s2, s3.substring(0,k))||isInterleave(s1, s2.substring(0,j), s3.substring(0,k));
		}
		return false;
    }
}
这个题应该用动态规划算法,dp[i][j]表示用s1的前i个字符和s2的前j个字符能不能按照规则表示出s3的前i+j个字符,如此最后结果就是dp[s1.length()][s2.length()],判断是否为真即可。
public class Solution {
    boolean dp[][];  
	public boolean isInterleave(String s1, String s2, String s3){  
        int size1 = s1.length();  
        int size2 = s2.length();  
        int size3 = s3.length();  
        if( size1 + size2 != size3) return false;  
          
        dp=new boolean[size1+1][size2+1]; 
        dp[0][0] = true;  
        for(int i = 1; i <= size1; ++i)  
            if(s1.charAt(i-1) == s3.charAt(i-1)) dp[i][0] = true;  
            else break;  
        for(int j = 1; j <= size2; ++j)  
            if(s2.charAt(j-1) == s3.charAt(j-1)) dp[0][j] = true;  
            else break;  
  
        int k;  
        for(int i = 1; i <= size1; ++i)  
            for(int j = 1; j <= size2; ++j)  
            {  
                k = i + j;  
                if(s1.charAt(i-1) == s3.charAt(k-1)) dp[i][j] = dp[i-1][j] || dp[i][j];  
                if(s2.charAt(j-1) == s3.charAt(k-1)) dp[i][j] = dp[i][j-1] || dp[i][j];  
            }  
        return dp[size1][size2];  
    }  
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值