持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第33天,点击查看活动详情
力扣——1647. 字符频次唯一的最小删除次数
1647. 字符频次唯一的最小删除次数
如果字符串 s 中 不存在 两个不同字符 频次 相同的情况,就称 s 是 优质字符串 。
给你一个字符串 s,返回使 s 成为 优质字符串 需要删除的 最小 字符数。
字符串中字符的 频次 是该字符在字符串中的出现次数。例如,在字符串 "aab" 中,'a' 的频次是 2,而 'b' 的频次是 1 。
示例 1:
输入:s = "aab"
输出:0
解释:s 已经是优质字符串。
示例 2:
输入:s = "aaabbbcc"
输出:2
解释:可以删除两个 'b' , 得到优质字符串 "aaabcc" 。
另一种方式是删除一个 'b' 和一个 'c' ,得到优质字符串 "aaabbc" 。
提示:
1 <= s.length <= 105s仅含小写英文字母
问题解析
因为我们只能通过删除字符来改变它的出现次数。
那么如果有多个字符的出现次数相同时,我们可以选择把除了某个字符以外的其它字符都删掉一个。即如果有n个字符的出现次数都是m,那就把n-1个字符都删去一个,使得他们的出现次数变成m-1。如果出现次数为m-1的字符也有多个,就重复之前的操作。
- 先用哈希表记录下每个字符的出现次数,cnt记录要删除的字符数。
- 准备一个数组f,f[i]表示出现次数为i的字符有f[i]个。
- 从i=n开始一直遍历数组,当f[i]>1时有cnt+=f[i]-1,f[i-1]+=f[i]-1。
- 当i=0时,结束遍历
- 返回cnt
AC代码
class Solution {
public:
unordered_map<char,int>mymap;
int f[100050];
int minDeletions(string s) {
for(auto&i:s)mymap[i]++;
for(auto&i:mymap)
{
f[i.second]++;
}
int n=s.size(),cnt=0;
for(int i=n;i>=1;i--)
{
if(f[i]>1)
{
cnt+=f[i]-1;
f[i-1]+=f[i]-1;
}
}
return cnt;
}
};