LeetCode 1092. 最短公共超序列--最长公共子序列

  1. 最短公共超序列

给出两个字符串 str1 和 str2,返回同时以 str1 和 str2 作为子序列的最短字符串。如果答案不止一个,则可以返回满足条件的任意一个答案。

(如果从字符串 T 中删除一些字符(也可能不删除,并且选出的这些字符可以位于 T 中的 任意位置),可以得到字符串 S,那么 S 就是 T 的子序列)

示例:

输入:str1 = “abac”, str2 = “cab”
输出:“cabac”
解释:
str1 = “abac” 是 “cabac” 的一个子串,因为我们可以删去 “cabac” 的第一个 "c"得到 “abac”。
str2 = “cab” 是 “cabac” 的一个子串,因为我们可以删去 “cabac” 末尾的 “ac” 得到 “cab”。
最终我们给出的答案是满足上述属性的最短字符串。

提示:

1 <= str1.length, str2.length <= 1000
str1 和 str2 都由小写英文字母组成。

题解

先动态规划找出最长公共子序列,记录路径,得到最长公共子序列部分,然后分别和两个字符串对应找没有的部分,加进来就行。

AC代码

class Solution {
public:
   
    int dp[1005][1005],path[1005][1005][2];//path为最长公共序列路径
    string s[1005];
    string shortestCommonSupersequence(string str1, string str2) 
    {
        memset(dp,0,sizeof(dp));
        memset(path,0,sizeof(path));
        string res = "";
        for(int i=0;i<str1.length();i++)
        {
            for(int j=0;j<str2.length();j++)
            {
                if(str1[i] == str2[j])
                {
                    dp[i+1][j+1] = dp[i][j] + 1;
                    path[i+1][j+1][0] = i;
                    path[i+1][j+1][1] = j;
                }
                else
                {
                    if(dp[i][j+1]>dp[i+1][j])
                    {
                        dp[i+1][j+1] = dp[i][j+1];
                        path[i+1][j+1][0] = i;
                        path[i+1][j+1][1] = j+1;                       
                    }
                    else
                    {
                        dp[i+1][j+1] = dp[i+1][j];
                        path[i+1][j+1][0] = i+1;
                        path[i+1][j+1][1] = j;                        
                    }
                }
            }
        }
        int s1 = str1.length() , s2 = str2.length();
        while(s1!=0 && s2!=0)
        {
            if(str1[s1-1] == str2[s2-1])
            res += str1[s1-1];
            int s12 = path[s1][s2][0];
            int s22 = path[s1][s2][1];
            s1 = s12,s2 = s22;
        }
        reverse(res.begin(),res.end());
        //cout<
        s1 = 0 ,s2 = 0;
        while(s1<str1.length()&&s2<res.length())
        {
            if(str1[s1] == res[s2])
            {
                s1++;
                s2++;
            }
            else
            {
                s[s2] += str1[s1];
                s1++;
            }
        }
        while(s1<str1.length())
        {
            s[s2] += str1[s1];
            s1++;          
        }
        s1 = 0,s2 = 0;
        while(s1<str2.length()&&s2<res.length())
        {
            if(str2[s1] == res[s2])
            {
                s1++;
                s2++;
            }
            else
            {
                s[s2] += str2[s1];
                s1++;
            }
        }
        while(s1<str2.length())
        {
            s[s2] += str2[s1];
            s1++;
        }
        string fin = "";
        //cout<
        for(int i=0;i<res.length();i++)
        {
            fin += s[i];
            fin += res[i];
            //cout<
        }
        if(s[res.length()]!="")
        fin += s[res.length()];
        return fin;
    }
};

LeetCode 1092. 最短公共超序列--最长公共子序列_第1张图片

你可能感兴趣的:(LeetCode,动态规划,leetcode,算法,职场和发展)