Easy
题目描述
给定一个字符串 s,你有两种类型的操作:
- 选择字符串中的一个索引 i,设 c 为位置 i 处的字符。删除 i 左侧最接近的字符 c(如果存在)。
- 选择字符串中的一个索引 i,设 c 为位置 i 处的字符。删除 i 右侧最接近的字符 c(如果存在)。
你的任务是通过执行上述操作零次或多次来最小化 s 的长度。
返回一个整数,表示最小化字符串的长度。
示例 1:
输入:s = "aaabc"
输出:3
解释:
- 操作 2:选择 i = 1,c 是 'a',删除 s[2],因为它是 s[1] 右侧最接近的 'a' 字符。
字符串变为 "aabc"。
- 操作 1:选择 i = 1,c 是 'a',删除 s[0],因为它是 s[1] 左侧最接近的 'a' 字符。
字符串变为 "abc"。
示例 2:
输入:s = "cbbd"
输出:3
解释:
- 操作 1:选择 i = 2,c 是 'b',删除 s[1],因为它是 s[1] 左侧最接近的 'b' 字符。
字符串变为 "cbd"。
示例 3:
输入:s = "baadccab"
输出:4
约束条件:
- 1 <= s.length <= 100
- s 只包含小写英文字母
提示:
- 最小化后的字符串不会包含重复字符。
- 最小化后的字符串将包含原字符串的所有不同字符。
解题思路
解题思路
这道题的关键洞察在于理解操作的本质:无论我们如何选择删除顺序,对于任何重复出现的字符,我们都可以将其减少到只剩一个。
核心观察
- 操作的本质:每次操作都是删除某个字符的重复出现
- 最终状态:经过足够多的操作后,每个字符最多只会保留一个
- 顺序无关性:删除的顺序不影响最终结果
思路分析
由于题目提示告诉我们"最小化后的字符串将包含原字符串的所有不同字符"且"不会包含重复字符",这意味着最终结果就是原字符串中不同字符的个数。
无论我们选择什么样的删除策略,最终都能将所有重复字符消除,只保留每种字符的一个实例。
解法
最直接的解法就是统计字符串中不同字符的数量:
- 使用哈希集合存储所有出现过的字符
- 返回集合的大小
时间复杂度 O(n),空间复杂度 O(1)(最多26个小写字母)。
代码实现
class Solution {
public:
int minimizedStringLength(string s) {
unordered_set<char> unique_chars;
for (char c : s) {
unique_chars.insert(c);
}
return unique_chars.size();
}
};
class Solution:
def minimizedStringLength(self, s: str) -> int:
return len(set(s))
public class Solution {
public int MinimizedStringLength(string s) {
HashSet<char> uniqueChars = new HashSet<char>();
foreach (char c in s) {
uniqueChars.Add(c);
}
return uniqueChars.Count;
}
}
var minimizedStringLength = function(s) {
const uniqueChars = new Set();
for (const c of s) {
uniqueChars.add(c);
}
return uniqueChars.size;
};
复杂度分析
| 复杂度 | 大小 |
|---|---|
| 时间复杂度 | O(n) |
| 空间复杂度 | O(1) |
其中 n 是字符串的长度。空间复杂度为 O(1) 是因为最多只有 26 个不同的小写字母。