题目链接:https://leetcode.cn/problems/minimum-deletions-to-make-character-frequencies-unique/description/
题目大意:给出一个字符串s
,只包含小写字母。目标是【通过删除若干个字符】将其变为「每个字符出现的频次都不同」的字符串,求最小的删除字符数量。
思路:可以画一张柱状图,横坐标是出现频次,柱子的高度是这个出现频次的字符的个数。删除「n
个」字符意味着将某根柱子高度-1,让其左边「n
格」的柱子高度+1。最终目标是让所有柱子高度为1(但0频次可以有很多个,因为一个字符出现次数为0意味着删光了)。
很显然柱子的高度只能往左转移,那么从某根柱子开始向左找第一个高度为0的频次即可。不可能找不到,因为最终可以到达频次为0,也就是全删光。
用一个set记录高度大于1的柱子(频次,显然0除外),对它们进行贪心即可。
完整代码
cpp
class Solution {
public:
int minDeletions(string s) {
int freq[100001] = {};
int cnt[26] = {};
for (auto c : s) {
cnt[c-'a']++;
}
set<int> q;
for (int i = 0; i < 26; i++) {
if (cnt[i]) {
freq[cnt[i]]++;
if (freq[cnt[i]] > 1) {
q.insert(cnt[i]);
}
}
}
int ans = 0;
for (auto it = q.begin(); it != q.end(); it++) {
int idx = *it-1;
while (freq[*it] > 1) {
while (idx > 0 && freq[idx]) {
idx--;
}
freq[idx]++;
freq[*it]--;
ans += *it-idx;
}
}
return ans;
}
};