Keshawn_lu's Blog

Leetcode 1224. 最大相等频率

字数统计: 588阅读时长: 2 min
2022/08/18 Share

题目简介:

给你一个正整数数组 nums,请你帮忙从该数组中找出能满足下面要求的 最长 前缀,并返回该前缀的长度:

  • 从前缀中 恰好删除一个 元素后,剩下每个数字的出现次数都相同。

如果删除这个元素后没有剩余元素存在,仍可认为每个数字都具有相同的出现次数(也就是 0 次)。

示例 1:

1
2
3
输入:nums = [2,2,1,1,5,3,3,5]
输出:7
解释:对于长度为 7 的子数组 [2,2,1,1,5,3,3],如果我们从中删去 nums[4] = 5,就可以得到 [2,2,1,1,3,3],里面每个数字都出现了两次。

示例 2:

1
2
输入:nums = [1,1,1,2,2,2,3,3,3,4,4,4,5]
输出:13

提示:

  • 2 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^5

思路:

首先用哈希表记录每个数字出现的次数以及出现次数为f的数字个数freq[f],并记录数字出现次数的最大值max_freq

当我们遍历到nums[i]时,此时的前缀长度为i + 1

此时若需要满足题目要求,则分为三种情况:

  • max_freq = 1,也就是说每个数字出现的次数均为1,那么无论删除哪个数字都是满足要求的。
  • 有一个数字出现次数为max_freq,其余数字均为max_freq - 1,那么只要删除一个出现次数为max_freq的数字就行。
  • 有一个数字出现次数为1次,其余数字出现次数均为max_freq,那么删除那个出现次数为1次的即可。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
public:
int maxEqualFreq(vector<int>& nums) {

map<int, int> count, freq;

int res = 0;
int max_freq = 0;

for(int i = 0; i < nums.size(); i++){

if(count[nums[i]] > 0)
freq[count[nums[i]]]--; //更新,因为count[nums[i]]要增加了

count[nums[i]]++;
max_freq = max(max_freq, count[nums[i]]);
freq[count[nums[i]]]++;

bool accept = (max_freq == 1) //最大次数就为1,任意删除一个数字即可
|| (freq[max_freq] * max_freq + freq[max_freq - 1] * (max_freq - 1) == i + 1 && freq[max_freq] == 1) //max_freq只有一个数字,其余均为max_freq - 1
|| (freq[max_freq] * max_freq + 1 == i + 1 && freq[1] == 1); //除了一个数字出现次数为1,其余均为max_freq

if(accept)
res = max(res, i + 1); //更新最长前缀
}

return res;
}
};
CATALOG
  1. 1. 题目简介:
  2. 2. 思路:
  3. 3. 代码如下: