题目描述
1647. 字符频次唯一的最小删除次数
难度中等53收藏分享切换为英文接收动态反馈
如果字符串 s 中 不存在 两个不同字符 频次 相同的情况,就称 s 是 优质字符串 。
给你一个字符串 s,返回使 s 成为 优质字符串 需要删除的 最小 字符数。
字符串中字符的 频次 是该字符在字符串中的出现次数。例如,在字符串 "aab" 中,'a' 的频次是 2,而 'b' 的频次是 1 。
示例 1:
输入:s = "aab"
输出:0
解释:s 已经是优质字符串。
示例 2:
输入:s = "aaabbbcc"
输出:2
解释:可以删除两个 'b' , 得到优质字符串 "aaabcc" 。
另一种方式是删除一个 'b' 和一个 'c' ,得到优质字符串 "aaabbc" 。
示例 3:
输入:s = "ceabaacb"
输出:2
解释:可以删除两个 'c' 得到优质字符串 "eabaab" 。
注意,只需要关注结果字符串中仍然存在的字符。(即,频次为 0 的字符会忽略不计。)
提示:
1 <= s.length <= 105
s 仅含小写英文字母
思路:
1,确定字符串中的字母种类及一个字母出现的次数
2,对出现的次数进行排序(这里采用降序),根据题目要求 最小删除数就是不能有相同出现的频次 也就是说 对相同的频次减一 看有没有与减一之后再次相同的 如果有继续上述过程 如果无停止记录减一的次数 对每一个相同频次采用类似的处理方法
3,因为要求最小删除数 及最优解 那么可以用贪心算法
开辟一个数组 将其初始化为0 用频次作为下标 将该项赋值为1 如果频次相等 对其减一 有多少个相同频次进行多少次上述操作
直到减到频次为1 那么剩下的频次加上减一的次数即最小删除次数 ```
代码块
#define LETTER_NUM 26
#define MAX_LENGTH 100001
// 降序 比较函数
int cmp_down(const void *a, const void *b)
{
return (*(int *)b - *(int *)a);
}
int minDeletions(char *s)
{
int i;
int hash[LETTER_NUM] = {0}; // 统计字母出现个数
int flag[MAX_LENGTH] = {0}; // 标记是否已经出现过,出现flag = 1
int str_len = strlen(s);
int min_delete = 0;
for (i = 0; i < str_len; i++) {
hash[s[i] - 'a']++;
}
qsort(hash, LETTER_NUM, sizeof(int), cmp_down);
for (i = 0; i < LETTER_NUM; i++) {
// 如果出现次数为0,停止循环
if (hash[i] == 0) {
break;
}
// 如果没有出现过,标记为1
if (flag[hash[i]] == 0) {
flag[hash[i]] = 1;
} else {
while (1) {
min_delete++;
hash[i]--;//相当于下标
// 如果减小到数字0,跳出本次循环
if (hash[i] == 0) {
break;
}
// 如果减小到没有出现,标记为1,跳出本次循环
if (flag[hash[i]] == 0) {
flag[hash[i]] = 1;
break;
}
}
}
}
return min_delete;
}
递归思路
// 删除频次相同的最大次数字符中的1个即可,递归,计算depth
int cmp(const int *a, const int *b)
{
return *a - *b;
}
void dfs(int *dict, int dictSize, int *depth)
{
qsort(dict, dictSize, sizeof(int), cmp);
for (int i = 1; i < dictSize; i++) {
if (dict[i] == dict[i - 1] && dict[i] != 0) {
dict[i]--;
*depth += 1;
dfs(dict, dictSize, depth);
return;
}
}
return;
}
int minDeletions(char * s){
if (strlen(s) == 1) {
return 0;
}
int dict[26] = { 0 };
for (char *tmp = s; *tmp != '\0'; tmp++) {
dict[*tmp - 'a']++;
}
int depth = 0;
dfs(dict, sizeof(dict) / sizeof(int), &depth);
return depth;
}
如有其他解法相互分享