假设我们有一个字符串数组A,我们必须找到任何最小的字符串,其中包含A中的每个字符串作为子字符串。我们还可以假设A中的任何字符串都不是A中另一个字符串的子字符串。
因此,如果输入类似于[“ dbsh”,“ dsbbhs”,“ hdsb”,“ ssdb”,“ bshdbsd”],则输出将为“ hdsbbhssdbshdbsd”
为了解决这个问题,我们将遵循以下步骤-
定义一个函数calc()
,这将需要a,b,
对于初始化i:= 0,当i <a的大小时,更新(将i增加1),执行-
返回b的大小-a + i的大小
如果从索引i到结尾的a的子串位于b的开头,则-
b的返回值
从主要方法中,执行以下步骤
ret:=空字符串
n:= A的大小
定义一个大小为nxn的2D数组图-
graph [i,j]:= calc(A [i],A [j])
graph [j,i]:= calc(A [j],A [i])
对于初始化j:= 0,当j <n时,更新(将j增加1),执行-
定义大小为2 ^ nx n的数组dp。
定义大小为2 ^ nx n的数组路径。
minVal:= inf
最后:= -1
对于初始化i:= 0,当i <2 ^ n时,更新(将i增加1),执行-
dp [i,j]:= inf
对于初始化j:= 0,当j <n时,更新(将j增加1),执行-
对于初始化i:= 0,当i <2 ^ n时,更新(将i增加1),执行-
minVal:= dp [i,j]
最后:= j
如果i AND 2 ^ j不为零,则
如果prev与0相同,则-
除此以外
上一个:= i ^(2 ^ j)
dp [i,j]:= A [j]的大小
如果prev AND 2 ^ k和df [prev,k]不是inf且df [prev,k] + graph [k,j] <dp [i,j],则
dp [i,j]:= dp [prev,k] + graph [k,j]
路径[i,j]:= k
对于初始化k:= 0,当k <n时,更新(将k增加1),-
对于初始化j:= 0,当j <n时,更新(将j增加1),执行-
如果i与2 ^ n-1相同,并且dp [i,j] <minVal,则-
curr:= 2 ^ n-1
定义一个堆栈st
当curr> 0时,执行-
最后插入st
temp:= curr
curr:= curr-(2 ^ last)
最后:=路径[温度,最后]
i:= st的顶部元素
从st删除元素
ret:= ret + A [i]
虽然(不是st为空),请-
j:= st的顶部元素
从st删除元素
ret:= ret连接A [j]的子字符串,从(A [j]的大小-graph [i,j]到结尾)
i:= j
返回ret
让我们看下面的实现以更好地理解-
#include <bits/stdc++.h> using namespace std; class Solution { public: int calc(string& a, string& b){ for (int i = 0; i < a.size(); i++) { if (b.find(a.substr(i)) == 0) { return b.size() - a.size() + i; } } return (int)b.size(); } string shortestSuperstring(vector<string>& A){ string ret = ""; int n = A.size(); vector<vector<int> > graph(n, vector<int>(n)); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { graph[i][j] = calc(A[i], A[j]); graph[j][i] = calc(A[j], A[i]); } } int dp[1 << n][n]; int path[1 << n][n]; int minVal = INT_MAX; int last = -1; for (int i = 0; i < (1 << n); i++) for (int j = 0; j < n; j++) dp[i][j] = INT_MAX; for (int i = 1; i < (1 << n); i++) { for (int j = 0; j < n; j++) { if ((i & (1 << j))) { int prev = i ^ (1 << j); if (prev == 0) { dp[i][j] = A[j].size(); } else { for (int k = 0; k < n; k++) { if ((prev & (1 << k)) && dp[prev][k] != INT_MAX && dp[prev][k] + graph[k][j] < dp[i][j]) { dp[i][j] = dp[prev][k] + graph[k][j]; path[i][j] = k; } } } } if (i == (1 << n) - 1 && dp[i][j] < minVal) { minVal = dp[i][j]; last = j; } } } int curr = (1 << n) - 1; stack<int> st; while (curr > 0) { st.push(last); int temp = curr; curr -= (1 << last); last = path[temp][last]; } int i = st.top(); st.pop(); ret += A[i]; while (!st.empty()) { int j = st.top(); st.pop(); ret += (A[j].substr(A[j].size() - graph[i][j])); i = j; } return ret; } }; main(){ Solution ob; vector<string> v = {"dbsh","dsbbhs","hdsb","ssdb","bshdbsd"}; cout << (ob.shortestSuperstring(v)); }
{"dbsh","dsbbhs","hdsb","ssdb","bshdbsd"}
输出结果
hdsbbhssdbshdbsd