题意
小U得到一个只包含小写字母的字符串 S。她可以执行如下操作:每次选择字符串中两个相同的字符删除,然后在字符串末尾添加一个任意的小写字母。小U想知道,最少需要多少次操作才能使得字符串中的所有字母都不相同?
思路分析
我们可以通过统计每个字符的出现次数来决定需要多少次操作。
- 每次操作的过程:从字符串中删除两个相同的字符,且在字符串的末尾添加一个新的字符。这个操作的目标是通过删除两个重复的字符来减少重复的字符数。
- 目标:让字符串中所有的字符都唯一。
详细步骤
-
统计字符频率:首先,统计字符串中每个字符出现的次数。
-
计算需要操作的次数:
- 如果一个字符的出现次数大于 1,我们就可以通过删除两个相同字符来减少其出现次数,每次删除两个字符会减少一个字符的出现次数。
- 例如,如果某个字符出现了
count次,最多可以进行count // 2次操作(每次操作删除两个相同字符)。 - 通过这些操作,字符的出现次数会减少到 1 次或者 0 次。
-
最终的目标:每个字符的出现次数要么是 1,要么是 0。我们要尽量减少重复字符,直到所有字符都不重复。
-
每次操作结束后添加一个新字符:每次删除两个相同字符,并在字符串末尾添加一个新字符,这个新字符不会影响已经存在的字符,因此我们只关心删除字符的次数。
解法
- 统计每个字符出现的次数。
- 对于每个出现次数大于 1 的字符,计算需要的操作次数。
- 累加所有字符的操作次数。
代码实现
#include <iostream>
#include <string>
#include <unordered_map>
int solution(const std::string& S) {
std::unordered_map<char, int> freq;
// 统计字符出现频率
for (char c : S) {
freq[c]++;
}
int operations = 0;
// 遍历所有字符频率,计算最少操作次数
for (auto& entry : freq) {
int count = entry.second;
// 如果count > 1,需要进行count / 2次操作来减少重复字符
if (count > 1) {
operations += count / 2;
}
}
return operations;
}
int main() {
std::cout << (solution("abab") == 2) << std::endl;
std::cout << (solution("aaaa") == 2) << std::endl;
std::cout << (solution("abcabc") == 3) << std::endl;
}
复杂度分析
- 时间复杂度:
O(n),其中n是字符串的长度。我们遍历一次字符串来统计字符频率,之后对字符频率进行一次遍历。 - 空间复杂度:
O(1),最多只有 26 个小写字母,因此空间复杂度为常数。