LeetCode 题解工作台
字符串连接删减字母
给你一个下标从 0 开始的数组 words ,它包含 n 个字符串。 定义 连接 操作 join(x, y) 表示将字符串 x 和 y 连在一起,得到 xy 。如果 x 的最后一个字符与 y 的第一个字符相等,连接后两个字符中的一个会被 删除 。 比方说 join("ab", "ba") = "ab…
3
题型
5
代码语言
3
相关题
当前训练重点
中等 · 状态·转移·动态规划
答案摘要
我们注意到,字符串连接时,字符串的第一个字符和最后一个字符会影响到连接后字符串的长度。因此,我们设计一个函数 $dfs(i, a, b)$,表示从第 个字符串开始连接,且此前已经连接的字符串的第一个字符为 ,最后一个字符为 时,连接后字符串的最小长度。 函数 $dfs(i, a, b)$ 的执行过程如下:
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 状态·转移·动态规划 题型思路
题目描述
给你一个下标从 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 个操作,你可以执行以下操作之一:
- 令
stri = join(stri - 1, words[i]) - 令
stri = join(words[i], stri - 1)
你的任务是使 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 。
提示:
1 <= words.length <= 10001 <= words[i].length <= 50words[i]中只包含小写英文字母。
解题思路
方法一:记忆化搜索
我们注意到,字符串连接时,字符串的第一个字符和最后一个字符会影响到连接后字符串的长度。因此,我们设计一个函数 ,表示从第 个字符串开始连接,且此前已经连接的字符串的第一个字符为 ,最后一个字符为 时,连接后字符串的最小长度。
函数 的执行过程如下:
- 如果 ,说明所有字符串已经连接完毕,返回 ;
- 否则,我们考虑将第 个字符串连接到已经连接的字符串的末尾或者开头,得到连接后字符串的长度 和 ,则 。
为了避免重复计算,我们使用记忆化搜索的方法。具体地,我们使用一个三维数组 存储所有的 的返回值。当我们需要计算 时,如果 已经被计算过,我们直接返回 ;否则我们按照上述的递推关系计算 的值,并将其存入 中。
在主函数中,我们直接返回 。
时间复杂度 ,空间复杂度 ,其中 表示字符串的最大长度。
class Solution:
def minimizeConcatenatedLength(self, words: List[str]) -> int:
@cache
def dfs(i: int, a: str, b: str) -> int:
if i >= len(words):
return 0
s = words[i]
x = dfs(i + 1, a, s[-1]) - int(s[0] == b)
y = dfs(i + 1, s[0], b) - int(s[-1] == a)
return len(s) + min(x, y)
return len(words[0]) + dfs(1, words[0][0], words[0][-1])
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | Depends on the final approach |
| 空间 | Depends on the final approach |
面试官常问的追问
外企场景- question_mark
The candidate demonstrates understanding of dynamic programming and its application to string manipulation.
- question_mark
The candidate correctly identifies the state transition process and efficiently computes the minimum length.
- question_mark
The candidate uses memoization to avoid redundant calculations, ensuring the solution is optimized.
常见陷阱
外企场景- error
Failing to account for the deletion of characters when joining strings, leading to incorrect length calculations.
- error
Using a brute force approach instead of dynamic programming, resulting in inefficient solutions for larger input sizes.
- error
Not properly applying memoization, leading to redundant calculations and performance issues.
进阶变体
外企场景- arrow_right_alt
Extend the problem to handle larger character sets or longer strings.
- arrow_right_alt
Introduce additional constraints, such as limiting the number of allowed join operations.
- arrow_right_alt
Modify the problem to allow for multiple deletions when joining strings with matching characters.