携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情
【LeetCode每日一题】1224.最大相等频率
题目难度:困难
题意
给你一个正整数数组 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
提示:
题解:转换思维+分情况讨论
题解参考【宫水三叶】姐姐题解:题解地址
首先设置几个数据结构:
- cnt[i]:表示数字i出现的频率
- num_sum[i]:表示频率为i对应的不同数值有多少个
- max_cnt:表示最大的频率
遍历整个数组,假设当前遍历位置为i,如果当前的前缀能够满足题意,则必须满足以下三种情况之一(下面出现的):
- 所有的数值出现的频率均为1(即:)
- 除某一个值外,所有的数值出现的频率为,同时某一个数值出现的频率为max_cnt(即:(,为什么需要+1,因为"某个数值"-1后,频率会从max_cnt变成max_cnt-1。)
- 除某一个值外,其他的所有数值出现频率为max_cnt,同时某一个值出现的频率为1(即:)
C++代码
class Solution {
public:
int cnt[100005]; //cnt[i]:表示i出现的次数
int num_sum[100005]; //num_sum[i]:表示频率为i对应的不同数值有多少个
int maxEqualFreq(vector<int>& nums) {
int n=nums.size();
int max_cnt=0; //最大的频率
int ans=0;
for(int i=0;i<n;i++){
int x=++cnt[nums[i]];
num_sum[x]++;num_sum[x-1]--;
int len = i+1;
if(x>max_cnt) max_cnt=x;
if(max_cnt == 1) ans=len;
else if(num_sum[max_cnt]==1 && ( (num_sum[max_cnt-1]+1)*(max_cnt-1) +1 == len) ) ans=len;
else if(num_sum[max_cnt]*max_cnt+1 == len) ans=len;
}
return ans;
}
};