LeetCode每日一题(943. Find the Shortest Superstring)

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
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值