943. Find the Shortest Superstring
https://leetcode.com/problems/find-the-shortest-superstring/description/
/*
* @lc app=leetcode id=943 lang=cpp
*
* [943] Find the Shortest Superstring
*
* https://leetcode.com/problems/find-the-shortest-superstring/description/
*
* algorithms
* Hard (38.95%)
* Likes: 199
* Dislikes: 57
* Total Accepted: 6K
* Total Submissions: 15.3K
* Testcase Example: '["alex","loves","leetcode"]'
*
* Given an array A of strings, find any smallest string that contains each
* string in A as a substring.
*
* We may assume that no string in A is substring of another string in A.
*
*
*
*
* Example 1:
*
*
* Input: ["alex","loves","leetcode"]
* Output: "alexlovesleetcode"
* Explanation: All permutations of "alex","loves","leetcode" would also be
* accepted.
*
*
*
* Example 2:
*
*
* Input: ["catg","ctaagt","gcta","ttca","atgcatc"]
* Output: "gctaagttcatgcatc"
*
*
*
*
*
* Note:
*
*
* 1 <= A.length <= 12
* 1 <= A[i].length <= 20
*
*
*
*
*
*/
class Solution {
public:
string shortestSuperstring(vector<string>& A) {
const auto dist = [](const string &a, const string &b) {
int d = b.length();
for (int k = 1; k <= min(a.length(), b.length()); ++k) {
if (a.substr(a.size() - k) == b.substr(0, k)) d = b.length() - k;
}
return d;
};
const int N = A.size();
vector<vector<int>> g(N, vector<int>(N));
for (int i = 0; i < N; ++i) {
for (int j = i + 1; j < N; ++j) {
g[i][j] = dist(A[i], A[j]);
g[j][i] = dist(A[j], A[i]);
}
}
// <哪些被访问过的状态,末尾>
vector<vector<int>> dp(1 << N, vector<int>(N, INT_MAX / 2));
vector<vector<int>> parent(1 << N, vector<int>(N, -1));
for (int i = 0; i < N; ++i) dp[1 << i][i] = A[i].length();
for (int s = 1; s < (1 << N); ++s) {
for (int i = 0; i < N; ++i) {
// i没有访问过,跳过
if (!(s & (1 << i))) continue;
// i 位置空,即上一状态
int prev = s - (1 << i);
for (int j = 0; j < N; ++j) {
if (dp[prev][j] + g[j][i] < dp[s][i]) {
dp[s][i] = dp[prev][j] + g[j][i];
parent[s][i] = j;
}
}
}
}
auto it = min_element(begin(dp.back()), end(dp.back()));
int cur = it - begin(dp.back());
int s = (1 << N) - 1;
string res;
while (s) {
int prev = parent[s][cur];
if (prev < 0) res = A[cur] + res;
else res = A[cur].substr(A[cur].length() - g[prev][cur]) + res;
s &= ~(1 << cur);
cur = prev;
}
return res;
}
};
Last updated