本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。

为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库:https://github.com/memcpy0/LeetCode-Conquest。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。

由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。

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

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

注意:

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

示例 1:

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

示例 2:

输入:word = "aazz"
输出:false
解释:我们必须删除一个字母,所以要么 "a" 的频率变为 1 且 "z" 的频率为 2 ,要么两个字母频率反过来。所以不可能让剩余所有字母出现频率相同。

提示:

  • 2 <= word.length <= 100
  • word 只包含小写英文字母。

解法1 暴力枚举删除的字符

枚举 w o r d [ i ] word[i] word[i] ,将其去掉后再统计剩余字符的出现次数。用数组或者哈希表统计都行。如果剩余字符的出现次数都相同,则返回 true 。反之,如果无论去掉哪个 w o r d [ i ] word[i] word[i] ,都无法让剩余字符的出现次数都相同,则返回 false

class Solution {bool isSame(unordered_map<char, int> &cnt) {int c0 = cnt.begin()->second;for (auto &[_, c] : cnt) if (c != c0) return false;return true;}
public:bool equalFrequency(string word) { for (int i = 0, n = word.size(); i < n; ++i) { // 枚举删除的字符unordered_map<char, int> cnt;for (int j = 0; j < n; ++j)if (j != i) ++cnt[word[j]]; // 统计出现次数if (isSame(cnt)) // 出现次数都一样return true;} return false;}
};

复杂度分析:

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2) ,其中 n 为 w o r d word word 长度。
  • 空间复杂度: O ( ∣ Σ ∣ ) O(|\Sigma|) O(∣Σ∣),其中 ∣ Σ ∣ |\Sigma| ∣Σ∣ 为字符集的大小,本题字符均为小写字母,所以 ∣ Σ ∣ = 26 |\Sigma| =26 ∣Σ∣=26 。

解法2 分类讨论

如果有至少三种不同的出现次数,无论去掉哪个字符,剩下的出现次数仍然至少有两种。所以只需要讨论出现次数至多两种的情况

  1. 如果出现次数只有一种:

    1. 如果只有一种字符,例如 "aaaaa" \texttt{"aaaaa"} "aaaaa" ,那么无论删除哪个都是满足要求的。
    2. 如果每个字符恰好出现一次,例如 "abcde" \texttt{"abcde"} "abcde" ,那么无论删除哪个都是满足要求的。代码实现时,可以合并到下面的「较少的出现次数恰好是 1 1 1 」的情况中。
    3. 如果每个字符出现不止一次,例如 "aabbcc" \texttt{"aabbcc"} "aabbcc" ,虽然出现次数均为 2 2 2 ,但题目要求恰好去掉一个字符,所以无法满足要求。
  2. 如果出现次数有两种,那么必须变成一种
    1. 考虑去掉出现次数较少的字符它的出现次数必须恰好是 1 1 1 ,且只有这一种字符出现一次。例如 "abbbccc" \texttt{"abbbccc"} "abbbccc" ,去掉只出现一次的字符,就能满足要求。但如果它的出现次数大于 1 1 1 ,例如 "aabbbccc" \texttt{"aabbbccc"} "aabbbccc" ,就无法满足要求。
    2. 考虑去掉出现次数较多的字符它的出现次数必须比出现次数较少的恰好多 1 1 1,且只有这一种字符出现一次。例如 "aabbccc" \texttt{"aabbccc"} "aabbccc" 去掉 c \texttt{c} c 是可以满足要求的。其它情况如 "abccc" \texttt{"abccc"} "abccc" 或 "abccdd" \texttt{"abccdd"} "abccdd" 都是无法满足要求的。
class Solution {
public:bool equalFrequency(string word) { unordered_map<char, int> rec;for (char c : word) ++rec[c];vector<int> cnt;for (auto &[_, c] : rec) cnt.push_back(c);sort(cnt.begin(), cnt.end()); // 出现次数从小到大排序// 只有1种字符 or 去掉次数最少的 or 出掉次数最多的return cnt.size() == 1 || cnt[0] == 1 && equal(cnt.begin() + 2, cnt.end(), cnt.begin() + 1) ||cnt.back() == cnt[cnt.size() - 2] + 1 && equal(cnt.begin() + 1, cnt.end() - 1, cnt.begin());}
};

复杂度分析:

  • 时间复杂度: O ( n + ∣ Σ ∣ log ⁡ ∣ Σ ∣ ) O(n+|\Sigma|\log |\Sigma|) O(n+∣Σ∣log∣Σ∣) ,其中 n 为 w o r d word word 长度, ∣ Σ ∣ |\Sigma| ∣Σ∣ 为字符集的大小,本题字符均为小写字母,所以 ∣ Σ ∣ = 26 |\Sigma| =26 ∣Σ∣=26 。
  • 空间复杂度: O ( ∣ Σ ∣ ) O(|\Sigma|) O(∣Σ∣) 。

是可以优化到 O ( n ) O(n) O(n) 复杂度的,但对本题来说没有太多意义:

class Solution {public:bool equalFrequency(string word) {int cnt[26]{};for(char c : word) ++cnt[c-'a'];int maxCnt = 0, minCnt = word.size();int allCntCnt = 0; // 出现的字符种数for(int i = 0; i < 26; ++i) {if (cnt[i]) {++allCntCnt;maxCnt=max(cnt[i], maxCnt);minCnt=min(cnt[i], minCnt);}}// (出现次数只有一种): 所有字符出现次数为1或只有一种字符的情况if (allCntCnt == 1 || maxCnt == 1) return true;int maxCntCnt = 0; // 出现次数最多的字符种数for(int i = 0; i < 26; ++i)if (cnt[i] == maxCnt)++maxCntCnt;// 出现次数最大的字符和出现次数最少的字符仅相差1次, 且只有一种出现次数最大的字符// 或者出现次数最少的字符次数为1次, 且其它字符出现次数均相同return (maxCnt - minCnt == 1 && maxCntCnt == 1) || (minCnt == 1 && maxCntCnt == allCntCnt - 1);}
};

LeetCode 2423. Remove Letter To Equalize Frequency【哈希表】简单相关推荐

  1. 【Leetcode】2423. Remove Letter To Equalize Frequency

    题目地址: https://leetcode.com/problems/remove-letter-to-equalize-frequency/description/ 给定一个长nnn字符串sss, ...

  2. LeetCode 890. 查找和替换模式(哈希表)

    1. 题目 你有一个单词列表 words 和一个模式 pattern,你想知道 words 中的哪些单词与模式匹配. 如果存在字母的排列 p ,使得将模式中的每个字母 x 替换为 p(x) 之后,我们 ...

  3. LeetCode 567. 字符串的排列 (滑动窗口哈希表)

    567. 字符串的排列 题意: 第一个字符串的排列之一是第二个字符串的子串 即判断第二个字符串是否包含某个子串,这个子串的字符以及字符数量要求与第一个字符串相同 解法1 (暴力法) 按照第一个字符串的 ...

  4. LeetCode 2353. 设计食物评分系统 维护哈希表+set

    设计一个支持下述操作的食物评分系统: 修改 系统中列出的某种食物的评分. 返回系统中某一类烹饪方式下评分最高的食物. 实现 FoodRatings 类: FoodRatings(String[] fo ...

  5. 127. Leetcode 242. 有效的字母异位词 (哈希表)

    class Solution:def isAnagram(self, s: str, t: str) -> bool:record = [0] * 26for i in range(len(s) ...

  6. leetcode 454. 四数相加 II(哈希表)

    给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 为了使问题简单化,所有的 A ...

  7. LeetCode 454. 四数相加 II【哈希表】

    454. 四数相加 II 给你四个整数数组 nums1.nums2.nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 <= i, j ...

  8. LeetCode练习五:哈希表

    文章目录 一.哈希表 1.1 哈希表简介 1.2 哈希函数 1.2.1 直接定址法 1.2.2 除留余数法 1.2.3 平方取中法 2.4 基数转换法 1.3 哈希冲突 1.3.1 开放地址法 1.3 ...

  9. LeetCode 26 Remove Duplicates from Sorted Array [Array/std::distance/std::unique] c++

    LeetCode 26 Remove Duplicates from Sorted Array [Array/std::distance/std::unique] <c++> 给出排序好的 ...

最新文章

  1. TI-DM8127:MCFW、ISS中对sensor的驱动和控制
  2. Javascript基础知识篇(5): 面向对象之链式调用
  3. 【晒出你的第83行代码】踌躇满志的三位高中生,以敬畏之心踏上了代码征程...
  4. 在Ubuntu/mint里安装VMware tools(虚拟机增强工具)
  5. WPF学习一--概述
  6. 舞蹈链(DLX)模板
  7. 前端学习(2649):vue3.0的处理展示
  8. git找回当前目录下误删的所有文件
  9. android 广告设置秒数,Android动态显示具体到秒的相聚时间
  10. Oracle删除用户和表空间
  11. Pollard-Rho Algorithm简述
  12. 互联网技术人应该如何与上级沟通?
  13. 二维码制作教程分享,大家一起来学习吧!
  14. 压缩图片和改变图片图形
  15. zend_Zend认证工程师
  16. win32 20子窗口控件的代码
  17. Unity图集简介及使用
  18. “数学界的诺贝尔奖”出炉,4人获奖
  19. vps文件服务器,vps搭建媒体文件服务器
  20. matlab 画非线性曲线,MATLAB实例:非线性曲线拟合

热门文章

  1. k-means+matlab 之辣鸡学算法
  2. 无人机领域重大进展,即将实现空中充电
  3. 浅谈git rebase和git checkout --ours(theirs)
  4. 第二部分 区块链的应用
  5. 浅谈 2017 Google I/O 开发者大会
  6. 异常处理·MSSQL·在将nvarchar值‘XXX‘转换成数据类型int时失败
  7. ARM体系结构与编程学习(四)
  8. MOOC - 数据库系统概论(基础篇)- 第二次考试
  9. 开源 word 替代_5种Google文档的开源替代品
  10. 上天、入水、下地,清洁机器人蓝海有多大?