leetcode 1092. 最短公共超序列

给出两个字符串 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 都由小写英文字母组成。

解题思路:

设dp[i + 1][j + 1]为str1[0 , i] 和str2[0 , j]的最短公共超序列 的长度;

当str1[i] == str2[j]时,dp[i + 1][j + 1] = dp[i][j] + 1 ;

当str1[i] != str2[j]时, 判断谁是最短公共超序列的最后一个字符,如果是str1[i],那么dp[i + 1][j + 1] = dp[i][j + 1] + 1  ;

如果是str2[j] , 那么dp[i + 1][j + 1] = dp[i + 1][j ] + 1  ;

然后根据dp[i+1][j + 1]的关系,逆序将字符连接到res中;

class Solution {
public:
    string shortestCommonSupersequence(string str1, string str2) 
    {
        int n1 = str1.size() , n2 = str2.size() ;
        vector> dp(n1 + 1 , vector(n2 + 1, 0)) ;
        
        for(int j = 0 ; j < n2 ; ++j) dp[0][j + 1] = dp[0][j] + 1 ;
        for(int i = 0 ; i < n1 ; ++i) dp[i + 1][0] = dp[i][0] + 1 ;
        for(int i = 0 ; i < n1 ; ++i)
            for(int j = 0  ; j < n2 ; ++j)
            {
                if(str1[i] == str2[j]) dp[i + 1][j + 1] = dp[i][j] + 1 ;
                else dp[i + 1][j + 1] = min(dp[i][j + 1] , dp[i + 1][j]) + 1;
            }
        
        int i = n1 - 1 , j = n2 - 1 ;
        string res ;
        while(i >= 0 && j >= 0)
        {
            if(str1[i] == str2[j])
            {
                res += str1[i] ;
                i-- ;
                j-- ;
            }
            else if(dp[i + 1][j + 1] == dp[i][j + 1] + 1)
            {
                res += str1[i] ;
                i-- ;
            }
            else
            {
                res += str2[j] ;
                j-- ;
            }
        }
        
        if(i < 0)
        {
            while(j >= 0) 
            {
                res += str2[j] ;
                j-- ;
            }
        }
        else
        {
            while(i >= 0) 
            {
                res += str1[i] ;
                i-- ;
            }
        }
        
        reverse(res.begin() , res.end()) ;
        
        return res ;
    }
};

 

你可能感兴趣的:(leetcode,动态规划)