列表

详情


6898. 字符串连接删减字母

给你一个下标从 0 开始的数组 words ,它包含 n 个字符串。

定义 连接 操作 join(x, y) 表示将字符串 x 和 y 连在一起,得到 xy 。如果 x 的最后一个字符与 y 的第一个字符相等,连接后两个字符中的一个会被 删除 。

比方说 join("ab", "ba") = "aba" , join("ab", "cde") = "abcde" 。

你需要执行 n - 1 次 连接 操作。令 str0 = words[0] ,从 i = 1 直到 i = n - 1 ,对于第 i 个操作,你可以执行以下操作之一:

你的任务是使 strn - 1 的长度 最小 

请你返回一个整数,表示 strn - 1 的最小长度。

 

示例 1:

输入:words = ["aa","ab","bc"]
输出:4
解释:这个例子中,我们按以下顺序执行连接操作,得到 str2 的最小长度:
str0 = "aa"
str1 = join(str0, "ab") = "aab"
str2 = join(str1, "bc") = "aabc" 
str2 的最小长度为 4 。

示例 2:

输入:words = ["ab","b"]
输出:2
解释:这个例子中,str0 = "ab",可以得到两个不同的 str1:
join(str0, "b") = "ab" 或者 join("b", str0) = "bab" 。
第一个字符串 "ab" 的长度最短,所以答案为 2 。

示例 3:

输入:words = ["aaa","c","aba"]
输出:6
解释:这个例子中,我们按以下顺序执行连接操作,得到 str2 的最小长度:
str0 = "aaa"
str1 = join(str0, "c") = "aaac"
str2 = join("aba", str1) = "abaaac"
str2 的最小长度为 6 。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int minimizeConcatenatedLength(vector<string>& words) { } };

java 解法, 执行用时: 52 ms, 内存消耗: 42.8 MB, 提交时间: 2023-06-25 09:43:33

class Solution {
    public int minimizeConcatenatedLength(String[] words) { 
        int inf = Integer.MAX_VALUE;
        int[][] cnt = new int[26][26];
        for (int i = 0; i < 26; i++) Arrays.fill(cnt[i], inf);
        // cnt[i][j]表示第一个字符为 i,最后一个字符为 j 的最短长度。
        cnt[words[0].charAt(0)-'a'][words[0].charAt(words[0].length()-1)-'a'] = words[0].length();
        for (int i = 1; i < words.length; i++) {
            String str = words[i];
            int[][] tmp = new int[26][26];
            for (int l = 0; l < 26; l++) Arrays.fill(tmp[l], inf);
            int l = str.charAt(0)-'a', r = str.charAt(str.length()-1)-'a';
            for (int j = 0; j < 26; j++) {
                for (int k = 0; k < 26; k++) {
                    if (cnt[j][k] != inf) {
                        int len = cnt[j][k]+str.length();
                        if (j == r) tmp[l][k] = Math.min(tmp[l][k], len-1);
                        else tmp[l][k] = Math.min(tmp[l][k], len);

                        if (k == l) tmp[j][r] = Math.min(tmp[j][r] , len-1);
                        else tmp[j][r] = Math.min(tmp[j][r] , len);
                    }
                }
            }
            cnt = tmp;
        }
        int res = Integer.MAX_VALUE;
        for (int i = 0; i < 26; i++) {
            for (int j = 0; j < 26; j++) {
                if (cnt[i][j] > 0) {
                    res = Math.min(res, cnt[i][j]);
                }
            }
        }
        return res;
    }
}

golang 解法, 执行用时: 76 ms, 内存消耗: 13.5 MB, 提交时间: 2023-06-25 09:42:20

// 动态规划
// dp[i][j][k],表示,从0到i的word,组成的以j开头、以k结尾的str,的最短长度
func minimizeConcatenatedLength(words []string) int {
	n := len(words)
	dp := make([][26][26]int, n)
	for i := range dp {
		for j := range dp[i] {
			for k := range dp[i][j] {
				dp[i][j][k] = math.MaxInt32
			}
		}
	}
	dp[0][words[0][0]-'a'][words[0][len(words[0])-1]-'a'] = len(words[0])
	for i := 1; i < n; i++ {
		si := int(words[i][0] - 'a')
		ei := int(words[i][len(words[i])-1] - 'a')
		l := len(words[i])
		for j := 0; j < 26; j++ {
			for k := 0; k < 26; k++ {
				if dp[i-1][j][k] == -1 {
					continue
				}
				if ei == j {
					dp[i][si][k] = min(dp[i][si][k], dp[i-1][j][k]+l-1)
				} else {
					dp[i][si][k] = min(dp[i][si][k], dp[i-1][j][k]+l)
				}
				if k == si {
					dp[i][j][ei] = min(dp[i][j][ei], dp[i-1][j][k]+l-1)
				} else {
					dp[i][j][ei] = min(dp[i][j][ei], dp[i-1][j][k]+l)
				}
			}
		}
	}
	res := math.MaxInt32
	for i := range dp[n-1] {
		for _, d := range dp[n-1][i] {
			res = min(res, d)
		}
	}
	return res
}

func min(a, b int) int { if a < b {	return a }; return b }

python3 解法, 执行用时: 388 ms, 内存消耗: 52.5 MB, 提交时间: 2023-06-25 09:40:18

'''
记忆化搜索
dfs(i, s, e): 第 i 次操作,前面字符串开头为 s,末尾为e形成的最短长度  
'''
class Solution:
    def minimizeConcatenatedLength(self, words: List[str]) -> int:
        @cache
        def dfs(i: int, s: str, e: str) -> int:
            if i == n:
                return 0
            string = words[i]
            res = dfs(i + 1, s, string[-1]) + len(string) - int(string[0] == e)
            res = min(res, dfs(i + 1,string[0], e) + len(string) - int(string[-1] == s))
            return res
        n = len(words)
        return dfs(1, words[0][0], words[0][-1]) + len(words[0])

上一题