Given an array of strings words, return the smallest string that contains each string in words as a substring. If there are multiple valid strings of the smallest length, return any of them.
You may assume that no string in words is a substring of another string in words.
Example 1:
Input: words = [“alex”,“loves”,“leetcode”]
Output: “alexlovesleetcode”
Explanation: All permutations of “alex”,“loves”,“leetcode” would also be accepted.
Example 2:
Input: words = [“catg”,“ctaagt”,“gcta”,“ttca”,“atgcatc”]
Output: “gctaagttcatgcatc”
Constraints:
- 1 <= words.length <= 12
- 1 <= words[i].length <= 20
- words[i] consists of lowercase English letters.
- All the strings of words are unique.
看得官方的解法, 不想多说了, 有兴趣的看原文
use std::collections::HashMap;
impl Solution {
fn dp(count: usize, overlaps: &Vec<Vec<usize>>, i: usize, mask: i32, cache: &mut HashMap<(usize, i32), (usize, Vec<usize>)>) -> (usize, Vec<usize>) {
if let Some(c) = cache.get(&(i, mask)) {
return c.clone();
}
if mask | (1 << i) == (1 << count) - 1 {
return (0, vec![i]);
}
let mut l = Vec::new();
for j in 0..count {
if i != j && mask & (1 << j) == 0 {
let (overlap, mut orders) = Solution::dp(count, overlaps, j, mask | (1 << i), cache);
orders.insert(0, i);
l.push((overlap + overlaps[i][j], orders));
}
}
let (overlap, order) = l.into_iter().max_by_key(|(l, _)| *l).unwrap();
cache.insert((i, mask), (overlap, order.clone()));
(overlap, order)
}
pub fn shortest_superstring(words: Vec<String>) -> String {
let mut overlaps = vec![vec![0; words.len()]; words.len()];
for i in 0..words.len() {
for j in 0..words.len() {
if i == j {
continue;
}
let mut overlap = 0;
let mut w1 = words[i].clone();
let mut w2 = words[j].clone();
let mut suffix = String::new();
let mut prefix = String::new();
while !(w1.is_empty() || w2.is_empty()) {
suffix.insert(0, w1.pop().unwrap());
prefix.push(w2.remove(0));
if suffix == prefix {
overlap = suffix.len();
}
}
overlaps[i][j] = overlap;
}
}
let mut cache = HashMap::new();
let mut l = Vec::new();
for i in 0..words.len() {
l.push(Solution::dp(words.len(), &overlaps, i, 0, &mut cache));
}
let (_, order) = l.into_iter().max_by_key(|(l, _)| *l).unwrap();
let mut prev_i = order[0];
let mut ans = words[order[0]].clone();
for i in order.into_iter().skip(1) {
let overlap = overlaps[prev_i][i];
let chars: Vec<char> = words[i].chars().collect();
for c in chars[overlap..].into_iter() {
ans.push(*c);
}
prev_i = i;
}
ans
}
}