「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」
题目
如果字符串 s 中 不存在 两个不同字符 频次 相同的情况,就称 s 是 优质字符串 。
给你一个字符串 s,返回使 s 成为 优质字符串 需要删除的 最小 字符数。
字符串中字符的 频次 是该字符在字符串中的出现次数。例如,在字符串 "aab" 中,'a' 的频次是 2,而 'b' 的频次是 1 。
- 数据量
- 字符串仅含小写英文字母
示例1
输入: s = "aab"
输出: 0
解释: s 已经是优质字符串。
示例2
输入:s = "aaabbbcc"
输出:2
解释:可以删除两个 'b' , 得到优质字符串 "aaabcc" 。
另一种方式是删除一个 'b' 和一个 'c' ,得到优质字符串 "aaabbc"
题解
常规思路+哈希表
已知字符串仅含小写英文字母,记录频次。这类问题可以压缩数据量,将字符串放入长度为26的数组中,数组下标表示字符串,数组元素表示字符串存在的数量。
比如字符串s = "aaabbbcc",字符串可以映射为数组下标[a,b,...,y,x] => [0,1,...,24,15]
- 假设数组list表示长度为26的数组,将字符串数据写入list数组,数组下标表示字符串,元素表示此字符串出出现的频次list = [3,3,2,0,...,0]
- 使用map记录list数组元素,因为重复的元素表示两个不同字符频次相同,需要删除相同频次的字符串,将重复的元素放入arry数组
- 枚举array数组,将array数组元素作为字符频次数量,迭代递减,迭代终止条件频次数量 或者 map中不存在这个数量
- 使用result变量记录迭代递减次数
- 返回result
整个过程逻辑还是比较清晰的
根据上述思路编辑代码如下:
代码
var minDeletions = function (s) {
const list = Array(26).fill(0);
for (let i = 0; i < s.length; i++) {
const k = s[i];
const idx = k.charCodeAt() - 'a'.charCodeAt();
list[idx]++;
}
const map = {};
let array = [];
for (let i = 0; i < 26; i++) {
const k = list[i];
if (k === 0) continue;
if (map[k]) {
array.push(k);
} else {
map[k] = 1;
}
}
let result = 0;
for (let i = 0; i < array.length; i++) {
let c = array[i];
while (map[c]) {
c--;
result++;
}
if (c > 0) map[c] = 1;
}
return result;
};