2020-5 leetcode 1092. 最短公共超序列

1.方法1:动态规划,对于每个 i j 1,为了省空间,可以翻滚处理数组的行
2.先找出来最长的公共子序列是存在于哪里,然后哪个最长不就代表答案最短吗。两个维护的东西都用动态规划来处理。

class Solution {
     
public:
    string shortestCommonSupersequence(string str1, string str2) {
     
        vector<vector<int>> d(2,vector<int>(str2.size()+1,0));
        vector<vector<string>> s(2,vector<string>(str2.size()+1,""));

        for(int i=0;i<=str1.size();i++){
     
            for(int j=0;j<=str2.size();j++){
     
                if(i==0||j==0){
     
                    d[i&1][j]=0;
                    if(i) s[i&1][j]=str1.substr(0,i);
                    if(j) s[i&1][j]=str2.substr(0,j);
                }
                else{
     
                    int a=d[(i-1)&1][j];
                    int b=d[i&1][j-1];
                    if(a<=b){
     
                        d[i&1][j]=b;
                        s[i&1][j]=s[i&1][j-1]+str2[j-1];
                    }
                    else{
     
                        d[i&1][j]=a;
                        s[i&1][j]=s[(i-1)&1][j]+str1[i-1];
                    }
                    if(str1[i-1]==str2[j-1]){
     
                        if(d[i&1][j]<d[(i-1)&1][j-1]+1){
     
                            d[i&1][j]=d[(i-1)&1][j-1]+1;
                            s[i&1][j]=s[(i-1)&1][j-1]+str2[j-1];
                        }
                    }
                }
            }
        }

        return s[str1.size()&1][str2.size()];
    }
};

方法2:1.先弄出最长公共子序列的长度,然后依据这个反推出最长公共子序列。
2.依据这个最长公共子序列来构造答案。(扣掉公共的不就只剩下各自的了吗)

#include
class Solution {
     
public:
    string shortestCommonSupersequence(string str1, string str2) {
     
        int n=str1.size(),m=str2.size();

        vector<vector<int>> dp(n+1,vector<int>(m+1,0));
        for(int i=1;i<=n;i++){
     
            for(int j=1;j<=m;j++){
     
                if(str1[i-1]==str2[j-1]){
     
                    dp[i][j]=dp[i-1][j-1]+1;
                }
                else{
     
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                }
            }
        }

        string lcs="";
        int i=n,j=m;

        while(i>0&&j>0){
     
            if(str1[i-1]==str2[j-1]){
     
                lcs+=str2[j-1];
                --i;
                --j;
            }
            else{
     
                dp[i-1][j]>dp[i][j-1]?--i:--j;
            }
        }

        reverse(lcs.begin(),lcs.end());

        string ans="";
        i=0,j=0;
        for(auto x:lcs){
     
            while(x!=str1[i]) ans+=str1[i++];
            while(x!=str2[j]) ans+=str2[j++];
            ans+=x;
            i++;
            j++;
        }
        ans+=str1.substr(i);
        ans+=str2.substr(j);

        return ans;
    }
};

你可能感兴趣的:(leetcode)