Description
Given two strings str1
and str2
, return the shortest string that has both str1
and str2
as subsequences. If multiple answers exist, you may return any of them.
(A string S is a subsequence of string T if deleting some number of characters from T (possibly 0, and the characters are chosen anywherefrom T) results in the string S.)
Example 1:
Input: str1 = "abac", str2 = "cab"
Output: "cabac"
Explanation:
str1 = "abac" is a substring of "cabac" because we can delete the first "c".
str2 = "cab" is a substring of "cabac" because we can delete the last "ac".
The answer provided is the shortest such string that satisfies these properties.
Note:
1 <= str1.length, str2.length <= 1000
str1
andstr2
consist of lowercase English letters.
思路
题意:构造一个字符串,使得其子序列同时包含有 str1 和 str2,要求这个字符串在满足要求情况下长度最短
题解:找出 str1 和 str2 的最长公共子序列,剩余不在最长公共子序列中的字符拼接到这个最长公共子序列中。
class Solution { public: string shortestCommonSupersequence(string str1, string str2) { string res = ""; int len1 = str1.size(), len2 = str2.size(); int dp[len1 + 5][len2 + 5]; memset(dp, 0, sizeof(dp)); int i, j; for (i = 1; i <= len1; i++){ for (j = 1; j <= len2; j++){ if (str1[i - 1] == str2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1; else dp[i][j] = dp[i][j - 1] > dp[i - 1][j] ? dp[i][j - 1] : dp[i - 1][j]; } } i = len1, j = len2; string common = ""; while (dp[i][j]){ if (dp[i][j] == dp[i - 1][j]) i--; else if (dp[i][j] == dp[i][j - 1]) j--; else common += str1[i - 1], i--, j--; } reverse(common.begin(), common.end()); int len3 = common.size(); i = 0, j = 0; for (int k = 0; k < len3; k++){ while (i < len1 && str1[i] != common[k]){ res += str1[i++]; } while (j < len2 && str2[j] != common[k]){ res += str2[j++]; } res += common[k]; i++; j++; } while (i < len1){ res += str1[i++]; } while (j < len2){ res += str2[j++]; } return res; } };