1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
func shortestSuperstring(words []string) string {
n := len(words)
overlap := make([][]int, n)
for i := range overlap {
overlap[i] = make([]int, n)
for j := range overlap[i] {
if i == j { continue }
for k := min(len(words[i]), len(words[j])); k > 0; k-- {
if words[i][len(words[i])-k:] == words[j][:k] {
overlap[i][j] = k; break
}
}
}
}
dp := make([][]int, 1<<n)
parent := make([][]int, 1<<n)
for i := range dp {
dp[i] = make([]int, n)
parent[i] = make([]int, n)
for j := range parent[i] { parent[i][j] = -1 }
}
for mask := 1; mask < 1<<n; mask++ {
for j := 0; j < n; j++ {
if mask&(1<<j) == 0 { continue }
pmask := mask ^ (1<<j)
if pmask == 0 { continue }
for i := 0; i < n; i++ {
if pmask&(1<<i) == 0 { continue }
val := dp[pmask][i] + overlap[i][j]
if val > dp[mask][j] {
dp[mask][j] = val
parent[mask][j] = i
}
}
}
}
mask, last, best := (1<<n)-1, 0, -1
for i := 0; i < n; i++ {
if dp[mask][i] > best { best = dp[mask][i]; last = i }
}
path := []int{}
for last != -1 {
path = append(path, last)
tmp := parent[mask][last]
mask ^= 1 << last
last = tmp
}
for i, j := 0, len(path)-1; i < j; i, j = i+1, j-1 {
path[i], path[j] = path[j], path[i]
}
seen := make([]bool, n)
ans := words[path[0]]
seen[path[0]] = true
for k := 1; k < len(path); k++ {
i, j := path[k-1], path[k]
ans += words[j][overlap[i][j]:]
seen[j] = true
}
for i := 0; i < n; i++ {
if !seen[i] { ans += words[i] }
}
return ans
}
func min(a, b int) int { if a < b { return a }; return b }
|