最少操作字符串次数
题目描述
解题思路
- 统计每个字符出现的次数:首先,要知道最少需要删除多少次字符就要知道每个字符的个数,我们可以使用一个长度为26(字符串S只包含小写字母,所以数组长度设置为26就可以了)的数组来记录每个字符的出现次数。
- 计算多余字符,对于任意一个字符,如果它的出现次数大于一次,那么我们就需要处理这些多余的重复字符,从题目中的描述“每次选择字符串中的两个相同的字符删除”我们可以知道,对于一个出现n(n>1)次的字符,需要进行n/2次操作来消除重复出现的字符。
-
- 这里为什么不是(n-1)/2呢?,因为n为偶数时,该字符在字符串会全部被清除,这样才不会有重复出现的字符,又因为整数在做除法时会进行下取整操作,所以直接用n/2就行了。
- 累加每个字符的操作次数,将所有字符的多余操作次数累加起来,就是最终需要的操作次数。
代码实现
function solution(S) {
// 初始化字符频率数组
let charCounts = new Array(26).fill(0);
// 统计每个字符出现的次数
for (let char of S) {
charCounts[char.charCodeAt(0) - 'a'.charCodeAt(0)]++;
}
// 计算需要的操作次数
let operations = 0;
for (let count of charCounts) {
if (count > 1) {
operations += count / 2;
}
}
return operations;
}
代码分析
时间复杂度
在这段代码中,我们使用了两个for循环遍历。
- 第一个是遍历字符串S,所有时间复杂度为O(n),n为字符串S的长度。
- 第二个是遍历charCounts数组,统计操作次数,charCounts数组长度固定为26,所有时间复杂度为O(26)
- 所以,最终的时间复杂度为O(n)
空间复杂度
- charCounts数组大小固定为26,空间复杂度为O(1)。
- operations变量占用常量空间,空间复杂度为为O(1)。
- 所有,最终的空间复杂度为O(1)
优点
- 代码结构清晰,逻辑简单易懂。
- 使用了数组来统计字符频率,避免了复杂的字典操作。
不足
- 未处理空字符串,代码没有处理空字符串的情况。(虽然不处理也能过,嘿嘿)虽然题目没有明确要求,但处理边界情况是一个好的编程习惯。
总结
该算法使用计数法和贪心策略来计算最少操作次数。首先,统计字符串中每个字符的出现频率,然后对于频率大于 1 的字符,通过移除一对重复字符来减少重复度,每个字符的重复度除以 2 即为所需操作数。最终累加这些操作数即可得到最小操作次数。