每日LeetCode —— 1224. 最大相等频率

61 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情

题目描述

       给定一个数组arr,要求找出数组的最大前缀,且该最大前缀满足:删除该前缀的某一元素后,前缀中的其他元素的个数相同。返回arr满足要求的最大前缀的长度。

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

解释:该用例中当前缀长度为8时,去除元素8后,剩余的元素个数均为1,不存在满足题目要求的更长的前缀,所以最大前缀的长度为8。

例1:输入:arr=[1,1]  输出:2

解释:当取前缀的长度为2时,去除一个元素1,剩下的元素1的个数为1,符合题目要求所以最长前缀长度为2。

本题值得注意的地方:

  • 当去除一个元素后剩下的前缀元素的个数为0时也是符合题意的。

原题地址:1224. 最大相等频率

解题思路

       通过题中对前缀的要求可以总结出以下几种情况:

  • 当前缀中所有的元素出现的次数都为1次时,在删除任意一个元素后其他元素出现的次数都是相同的为1。符合题目要求。
  • 当前缀中有一个元素出现的次数为1,其他元素出现的次数是相同的,这种情况在删除出现次数为1的那个元素后其他元素出现的次数是相同的,符合题目要求,例如[0,0,1,2,2],在删除元素1后剩下的元素个数相同。
  • 当前缀中元素的出现次数有两种情况,且较大的次数与较小的次数差值为1并且出现次数为较大次数的元素的个数为1次。这时删除较大次数的一个元素,剩下的元素出现的次数是相同的,例如[0,0,0,1,1],在删除0后剩下的元素出现的次数相同。

实现代码

class Solution {
public:
    int maxEqualFreq(vector<int>& nums) {
        int res=1, maxfreq=1;
        // 记录当前字串中元素出现的次数、每个次数的元素数
        map<int,int> count,freq;
        // 依次处理前缀
        for(int i=0; i<nums.size(); i++){
            // 当前元素出现的次数加1
            count[nums[i]]++;
            // 如果当前元素出现的次数大于1,则将当前次数-1中统计的元素数-1,将当前次数统计的元素数+1
            if(count[nums[i]]>1) freq[count[nums[i]]-1]--;
            freq[count[nums[i]]]++;
            // 维护元素出现的最大次数
            maxfreq=max(maxfreq,count[nums[i]]);
            // 对应上面结论的三种情况
            if(maxfreq == 1 || freq[maxfreq]*maxfreq + freq[maxfreq-1]*(maxfreq-1) == i+1&&freq[maxfreq] == 1 || freq[maxfreq]*maxfreq+1==i+1 && freq[1] == 1) res=i+1;
        }
        return res;
    }
};