0%

4-29每日

2423. 删除字符使频率相同

==Easy==

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

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

注意:

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

示例 1:

输入:word = "abcc"
输出:true
解释:选择下标 3 并删除该字母,word 变成 "abc" 且每个字母出现频率都为 1 。

题解

我们先用哈希表或者一个长度为 26 的数组 freq 统计字符串中每个字母出现的次数。

接下来,枚举 26 个字母,如果字母 s 在字符串中出现过,我们将其出现次数减一,然后判断剩余的字母出现次数是否相同。如果相同,返回 true,否则将 s 的出现次数加一,继续枚举下一个字母。

枚举结束,说明无法通过删除一个字母使得剩余字母出现次数相同,返回 false。

class Solution {
public:
    // 类成员变量 freq 数组,用于存储字符的出现次数
    int freq[26];
    
    bool equalFrequency(string word) {
        // 第一次遍历字符串,统计字符出现的次数
        for (char s : word) {
            ++freq[s - 'a'];
        }
        // 第二次遍历 freq 数组,依次将每个字符的出现次数减 1,判断剩余字符的频数是否相同
        for (int i = 0; i < 26; ++i) {
            if (freq[i] != 0) {
                freq[i]--; // 将当前字符的出现次数减 1
                bool flag = true; // 标记剩余字符是否频数相同的标志
                int x = 0; // 中间变量,用于存储某个字符的频数
                for(int j = 0; j < 26; ++j) {
                    if (freq[j] == 0) { // 如果这个字符的出现次数已经是 0,那么跳过它
                        continue;
                    }
                    else if (x == 0 && freq[j] != 0) { // 如果 x 是 0,并且这个字符的出现次数不是 0,那么将 x 赋值为这个字符的出现次数
                        x = freq[j];
                    }
                    else { // 如果 x 不是 0,并且这个字符的出现次数也不是 0
                        if (x == freq[j]) { // 如果 x 等于这个字符的出现次数,那么说明剩余字符的频数仍然相同
                            continue;
                        }
                        else { // 否则说明剩余字符的频数不相同
                            flag = false;
                        }
                    }
                }
                if (flag) { // 如果剩余字符的频数相同,那么说明存在一种方法,使得剩余字符的每个字符出现次数相等
                    return true;
                }
                else { // 否则说明剩余字符的频数不相同,恢复 freq 数组,并检查下一个字符
                    freq[i]++;
                    continue;
                }
            }
        }
        return false; // 如果遍历完 freq 数组都没有找到符合要求的字符,那么返回 false
    }
};