LeetCode-Interleaving String

本文详细介绍了如何解决LeetCode上的交错字符串问题,通过多种方法探讨了该问题的解决方案,包括简单的错误示例、递归方法、非递归实现及最终有效的动态规划方案。
作者:disappearedgod
时间:2014-6-13

题目

Interleaving String

  Total Accepted: 9375  Total Submissions: 50195 My Submissions

Given s1s2s3, 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.


解法

一个有问题的想法


public class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        int i = 0 , j = 0 , k = 0;
        char c1 , c2 , c3 ;
        int len1 = s1.length(), len2 = s2.length(), len3 = s3.length();
        if(len3 == 0)
            return len1 == 0 && len2 == 0;
        while((i<len1 || j<len2) && k < len3){
            c3 = s3.charAt(k);
            if(len1>i){
                c1 = s1.charAt(i);
                if(c3 == c1){
                    i++;
                    k++;
                    continue;
                }
                else
                    break;
                
            }
            if(len2>j){
                c2 = s2.charAt(j);
                if (c3 == c2){
                    j++;
                    k++;
                    continue;
                }
                else
                    break;
            }
            break;

         
        }
        
        return i ==len1 && j==len2  && k == len3;
        
    }
}

结果


Input:"aa", "ab", "aaba"
Output:false
Expected:true

递归想法


代码


public class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
         if(s3==null)
            return s1==null && s2==null;
        int len1 = 0, len2 = 0, len3 = 0;
        if(s1!=null)
            len1 = s1.length();
        if(s2!=null)
            len2 = s2.length();
        len3 = s3.length();
        if(len3!=len1+len2)
            return false;
        
        if( len1 == 0)
            return s2.equals(s3);
        if( len2 == 0)
            return s1.equals(s3);
        len1--;len2--;len3--;
        if(s1.charAt(0)==s3.charAt(0) && s2.charAt(0)==s3.charAt(0)){
            if(len1 > 0 && len2 > 0 && len3 > 0)
                return isInterleave(s1.substring(1,len1),s2,s3.substring(1,len3)) || isInterleave(s1,s2.substring(1,len2),s3.substring(1,len3));
            else if(len1 > 0 && len3 > 0)// len2++ == 1
                return isInterleave(s1.substring(1,len1),null,s3.substring(1,len3)) || isInterleave(s1.substring(1,len1),s2,s3.substring(1,len3));
            else if(len2 > 0 && len3 > 0)//len1++ == 1
                return isInterleave(null,s2,s3.substring(1,len3)) || isInterleave(s1,s2.substring(1,len2),s3.substring(1,len3));
            else
                return false;
            
            
        }
        else if(s1.charAt(0)==s3.charAt(0)){
            if(len1 > 0 && len3 > 0)
                return isInterleave(s1.substring(1,len1),s2,s3.substring(1,len3));
            else if(len3 > 0)
                return isInterleave(null,s2,s3.substring(1,len3));
            else
                return len2 == 0;
        }
        else if(s2.charAt(0)==s3.charAt(0)){
            if(len2 > 0  && len3 > 0)
                return isInterleave(s1,s2.substring(1,len2),s3.substring(1,len3));
            else if (len3 > 0)
                return isInterleave(s1,null,s3.substring(1,len3));
            else
                return len1 == 0;
        }
        else{
            return false;
        }
    }
    
}

结果


Last executed input:"bbbbbabbbbabaababaaaabbababbaaabbabbaaabaaaaababbbababbbbbabbbbababbabaabababbbaabababababbbaaababaa", "babaaaabbababbbabbbbaabaabbaabbbbaabaaabaababaaaabaaabbaaabaaaabaabaabbbbbbbbbbbabaaabbababbabbabaab", "babbbabbbaaabbababbbbababaabbabaabaaabbbbabbbaaabbbaaaaabbbbaabbaaabababbaaaaaabababbababaababbababbbababbbbaaaabaabbabbaaaaabbabbaaaabbbaabaaabaababaababbaaabbbbbabbbbaabbabaabbbbabaaabbababbabbabbab"


非递归思路

栈储存的思路

每次遇到s1,s2被指针指向的位置时候,储存相同的点。为了回退。(其实是递归的一种非递归实现,还是超时)
public class Solution {
    class Node{
        int x;
        int y;
        boolean isPop = false;
        Node(int i, int j, boolean bool){
            x = i;
            y = j;
            isPop = bool;
        }
    }
    public boolean isInterleave(String s1, String s2, String s3) {
        if(s3==null)
            return s1==null && s2==null;
        int len1 = 0, len2 = 0, len3 = 0;
        if(s1 != null)
            len1 = s1.length();
        if(s2 != null)
            len2 = s2.length();
        len3 = s3.length();
        if(len3 != len1+len2)
            return false;
        if( len1 == 0)
            return s2.equals(s3);
        if( len2 == 0)
            return s1.equals(s3);
        Queue<Node> q = new LinkedList<Node>();
        q.offer(new Node(0, 0, false));
        int i = 0, j = 0;
        while(!q.isEmpty()){
            Node node = q.poll();
            i = node.x;
            j = node.y;
            boolean isPop = node.isPop;
            char c1, c2, c3;
            while(i + j < len3){
                if(i < len1)
                    c1 = s1.charAt(i);
                else
                    c1 = '.';
                if(j < len2)
                    c2 = s2.charAt(j);
                else
                    c2 = '.';
                c3 = s3.charAt(i+j); 
                if(c1 == c3 && c2 == c3){
                    if(!isPop){
                        q.offer(new Node(i, j, true));
                        i++;
                    }
                    else{
                        j++;
                        isPop = false;
                    }
                }
                else if(c1 == c3){
                    i++;
                    if( i > len1)
                        return false;
                }
                else if(c2 == c3){
                    j++;
                    if(j > len2)
                        return false;
                }
                else{
                    break;
                }
            }
        }
        return i + j == len3;
    }
}

结果

Submission Result: Time Limit Exceeded
Last executed input: "cbcccbabbccbbcccbbbcabbbabcababbbbbbaccaccbabbaacbaabbbc", "abcbbcaababccacbaaaccbabaabbaaabcbababbcccbbabbbcbbb", "abcbcccbacbbbbccbcbcacacbbbbacabbbabbcacbcaabcbaaacbcbbbabbbaacacbbaaaabccbcbaabbbaaabbcccbcbabababbbcbbbcbb"


DP解法
想法
                     0 c a b       ccabcac
                0   1 0 0 0
                c   1 1 1 1 
                c   0 0 0 1
                a   0 0 0 1
                c   0 0 0 1
                
                     0 c a b       ccabcac
                0   1 ? 0 0
                c   ? 0 0 0 
                c   0 0 0 0
                a   0 0 0 0
                c   0 0 0 0
                
                     0    c   a   b       ccabcac
                0   1    0   0   0
                c   1    1   1   1 
                c   1-* 0   0   1
                a   1-* 0   0   1
                c   0    0   0   1
                
      0    c   a   b       ccabcac
                0   1    1   0   0
                c   1    1   1   1 
                c   1 0   0   1
                a   1 0   0   1
                c   0    0   0   1
                
           



代码
public class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        int l1 = s1.length();
        int l2 = s2.length();
        int l3 = s3.length();
        if(l1 != l3 -l2)
            return false;
        boolean [][] dp = new boolean[l1 + 1][l2 + 1];
        dp[0][0] = false;
        for(int k = 0; k < l3; k++){
            for(int i = 0; i < l3 && i < l1; i++){
                int j = k - i;
                if(j >= l2)
                    continue;
                dp[i + 1][j + 1] = false;
                if(s1.charAt(i) == s3.charAt(k) && dp[i][j + 1])
                    dp[i + 1][j + 1] = true;
                if(s2.charAt(j) == s3.charAt(k) && dp[i + 1][j])
                    dp[i + 1][j + 1] = true;
            }
            
        }
        return dp[l1][l2];
    }
}

结果

数组越界

改正

递推关系应该是由前面推向后面,所以要做到正好。

代码 

public class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        int l1 = s1.length();
        int l2 = s2.length();
        int l3 = s3.length();
        if(l1 != l3 -l2)
            return false;
        boolean [][] dp = new boolean[l1 + 1][l2 + 1];
        dp[0][0] = true;
        for(int k = 1; k <= l3; k++){
            for(int i = 0; i <= k && i <= l1; i++){
                int j = k - i;
                if(j > l2)
                    continue;
                dp[i][j] = false;
                if(i>0 && s1.charAt(i-1) == s3.charAt(k-1) && dp[i-1][j])
                    dp[i][j] = true;
                if(j > 0 && s2.charAt(j-1) == s3.charAt(k-1) && dp[i][j-1])
                    dp[i][j] = true;
            }
            
        }
        return dp[l1][l2];
    }
}


结果

Submit Time Status Run Time Language
3 minutes ago Accepted 444 ms java

参考

结果


返回



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值