Leetcode 97 交错字符串 (dp)

题目描述:

 

 题解:

普通的动态规划,dp[i][j]表示s1中前i个字符与s2中前j个字符交错形成s3前(i+j)个字符是否成立。状态转移的时候按照s3长度递增的顺序去推。

对于长度为i的情况,从s1,s2中找出与s3[i-1]相同的字符对应的位置k,然后用dp[i][i-k] = max(dp[i][i-k],dp[i-1][i-k]);

改进:用一位dp去实现,可以观察到状态转移方程是严格有序的,那么可以用一维的dp来去掉冗余的前缀。也就是滚动数组

 

AC代码:

普通dp

class Solution {
public:
    // 
    // 普通动规以及状压都试试
    bool isInterleave(string s1, string s2, string s3) {
        int Len1 = s1.length();
        int Len2 = s2.length();
        int Len3 = s3.length();
        if(Len1 == 0 && Len2 == 0 && Len3 == 0) return true;

        //cout<<Len1 <<" " <<Len2<<" " <<Len3<<endl; 

        if(Len3 != (Len1 + Len2)) return false;
        int dp[Len2+Len1+10][Len1+Len2+10];
        for(int i=0;i<Len2+Len1+10;i++)
        {
            for(int j=0;j<Len1+Len2+10;j++) dp[i][j] = 0;
        } 
        if(s1[0] == s3[0]) dp[1][0] = 1;
        if(s2[0] == s3[0]) dp[0][1] = 1;

// 重新处理
       // len
        for(int i=2;i<=Len3;i++)
        {
            for(int j=1;j<=min(i,Len1);j++) if(s1[j-1] == s3[i-1])
            {
                dp[j][i-j] = max(dp[j][i-j],dp[j-1][i-j]);
            }
            for(int j=1;j<=min(i,Len2);j++) 
            {
                if(s2[j-1] == s3[i-1])
                {
                    dp[i-j][j] = max(dp[i-j][j],dp[i-j][j-1]);
                }
            }
        }
        
        for(int i=1;i<=Len1;i++) if(dp[i][Len3-i] == 1) 
        {
            //cout << i <<" " <<Len3-i ;
            return true;
        }
        for(int i=1;i<=Len2;i++) if(dp[Len3-i][i] == 1) 
        {
          //  cout << Len3-i <<" " <<i;
            return true;
        }
        return false;
    }
};

 

posted @ 2020-02-13 17:22  猪突猛进!!!  阅读(130)  评论(0编辑  收藏  举报