Skip to content

Latest commit

 

History

History
118 lines (90 loc) · 3.71 KB

1224-maximum-equal-frequency.md

File metadata and controls

118 lines (90 loc) · 3.71 KB

1224. Maximum Equal Frequency - 最大相等频率

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

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

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

 

示例 1:

输入: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:

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

示例 3:

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

示例 4:

输入:nums = [10,2,8,9,3,8,1,5,2,3,7,6]
输出:8

 

提示:

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

题目标签:Hash Table

题目链接:LeetCode / LeetCode中国

题解

Language Runtime Memory
cpp 88 ms 18.4 MB
class Solution {
public:
    int maxEqualFreq(vector<int>& nums) {
        unordered_map<int, int> cnt;
        unordered_map<int, int> times;
        for (int num : nums) {
            cnt[num]++;
        }
        for (auto t = cnt.begin(); t != cnt.end(); t++) {
            times[t->second]++;
        }
        int res = nums.size();
        while (res > 0) {
            // cout << res << "\t| "; for (auto t = times.begin(); t != times.end(); t++) cout << t->first << ": " << t->second << "\t"; cout << endl;
            
            // 只有一种出现次数时,存在两种可能的情况:
            // 1. 出现1次的有x个,此时所有数都不一样
            // 2. 出现x次的只有1个,此时所有数都一样
            if (times.size() == 1 && (times.begin()->first == 1 || times.begin()->second == 1)) {
                return res;
            }
            if (times.size() == 2) {
                auto t = times.begin();
                auto a = t;
                t++;
                auto b = t;
                // 只有两种出现次数时,存在两种可能的情况:
                // 1. 出现1次的只有1个
                // 2. 出现n次的只有1个,且另一个是出现n-1次
                if (a->second == 1 && (a->first == 1 || a->first - 1 == b->first)) {
                    return res;
                }
                if (b->second == 1 && (b->first == 1 || b->first - 1 == a->first)) {
                    return res;
                }
            }
            
            res--;
            times[cnt[nums[res]]]--;
            // 当某个出现次数减为0时,从times中移除
            if (times[cnt[nums[res]]] == 0) {
                times.erase(cnt[nums[res]]);
            }
            cnt[nums[res]]--;
            // 注意:当出现次数为0时,不计入times
            if (cnt[nums[res]] > 0) {
                times[cnt[nums[res]]]++;
            }
        }
        return res;
    }
};