刷题记录(2023/4/29)2423. 删除字符使频率相同

0.前言

 因设置为私密总是找不到,就发出来了,本篇文章只是写给自己的,没有参考意义,请见谅

1.题目

给你一个下标从 0 开始的字符串 word ,字符串只包含小写英文字母。你需要选择 一个 下标并 删除 下标处的字符,使得 word 中剩余每个字母出现 频率 相同。

如果删除一个字母后,word 中剩余所有字母的出现频率都相同,那么返回 true ,否则返回 false 。

注意:

字母 x 的 频率 是这个字母在字符串中出现的次数。
你 必须 恰好删除一个字母,不能一个字母都不删除。

2.代码

2.1本人代码

分类讨论了好多,更改好几次,还是没出来,放弃了,哭死

class Solution {
public:
    bool equalFrequency(string word) {
        //关键:频率不同的值不能出现多次,也不能少于1(也不能少于1对于基准值为1的除外
        //1.选定一个频率的出现频率最高的,为主频率(统计频率时一个unordered_map,选取主频率时一个map
        //2.不等于该基准值的 数目应当>1或者(<1并且该基准值不能等于1),此时返回false
        unordered_map Map;
        for(char ch:word){
            if(Map.count(ch))   Map[ch]++;
            else    Map[ch]=1;
        }
        unordered_map M;
        for(auto p:Map){
            if(M.count(p.second))   M[p.second]++;
            else    M[p.second]=1;
        }
        int Max=0;          //Max为出现次数最多的 频率,而非频率的频率
        int imax=0;
        for(auto p:Map){
            Max=max(Max,p.second);
            if(imax

2.2官方代码

2.2.1题解一、暴力法

class Solution {
public:
    //暴力法
    bool equalFrequency(string word) {
        int charCount[26]={0};
        //1.得到每个元素的出现次数
        for(char& c:word){
            charCount[c-'a']++;
        }
        //2.遍历,即逐个删除然后进行判断
        for(int i=0;i<26;i++){
            //2.1删除操作
            if(charCount[i]==0) continue;
            charCount[i]--;
            //2.2判断操作
            unordered_set frequency;   //去重
            for(int f:charCount){
                if(f>0) frequency.insert(f);
            }
            if(frequency.size()==1) return true;
            charCount[i]++;
        }
        return false;
    }
};

2.2.2题解二、枚举+哈希表

方法一在每次删除之后,都需要重新统计每个字符出现频率,造成了重复运算,因此用哈希表进行优化

class Solution {
public:
    //哈希表+枚举
    bool equalFrequency(string word) {
        int charCount[26]={0};
        //1.得到每个元素的出现次数
        for(char c:word){
            charCount[c-'a']++;
        }
        //2.freqCount容器中存储<元素出现频率,该频率出现了多少次>
        unordered_map freqCount;
        for(int c:charCount){
            if(c>0) freqCount[c]++;
        }
        //3.同样,也是试着删除
        for(int c:charCount){   //c为某字母出现次数
            if(c==0)    continue;
            freqCount[c]--;
            //3.1如果该频率删除后就没有了,就去除该频率,以免影响 size 的计算
            if(freqCount[c]==0) freqCount.erase(c);
            //3.2如果出现次数>1,那么删除一个后,另一个频率的出现次数会改变
            if(c-1>0)   freqCount[c-1]++;
            if(freqCount.size()==1) return true;
            //3.3以下均为恢复操作,恢复到删除前的状态
            if(c-1>0){
                freqCount[c-1]--;
                if(freqCount[c-1]==0)   freqCount.erase(c-1);
            }
            freqCount[c]++;
        }
        return false;
    }
};

你可能感兴趣的:(leetcode,leetcode,算法,c++)