nums,从该数组中找出能满足下面要求的最长前缀,并返回该前缀的长度:
m1 记录的是数组中出现数值的频数,第二个哈希表 m2 记录的是 m1 中频数的频数,从前往后遍历数组并更新 m1、m2。【注意当 m2 中记录的数值为 0,则将对应键值对删除掉,即假若频数的频数变为 0,则从 m2 中去除掉影响】
m1 中的键值对记录的是数值和频数,m2 中的键值对记录的是频数和频数的频数。m2 中下面几种情况:
m2.size() == 1,即目前访问的前缀数组中只有一种频数,同时要满足以下两种情况其中一种:
1。【比如前缀数组为 1 2 3 4,此时数组中每个数值的频数均为 1,频数为 1 的频数为 4,此时删除任意一个数值都满足条件】1,但该频数的频数为 1,也满足条件。【比如前缀数组为 4 4 4,此时此时数组中每个数值的频数为 3,频数为 3 的频数为 1,此时删除任意一个数值都满足条件】m2.size() == 2,即目前访问的前缀数组中只有两种频数,同时也要满足以下两种情况其中一种:
1 且该频数的频数为 1。【比如前缀数组为 2 3 3 3 4 4 4】1,且更大的频数其频数为 1。【比如前缀数组为 2 2 3 3 4 4 4】class Solution
{
public:
int maxEqualFreq(vector<int>& nums)
{
unordered_map<int, int> m1;
map<int, int> m2; // m2有序,为了保证取出来的频数有序
int len = 0;
for(int i = 0; i < nums.size(); ++i)
{
int num = nums[i];
if(m1[num] > 0 and --m2[m1[num]] == 0)
m2.erase(m1[num]);
++m2[++m1[num]];
auto iter = m2.begin();
if(m2.size() == 1) // 对应情况 1
{
if(iter->first == 1 or iter->second == 1)
len = i+1;
}
else if(m2.size() == 2) // 情况 2
{
int a = iter->first; // 最小的频数
int c = iter->second; // 最小频数的频数
int b = (++iter)->first; // 最大的频数
int d = iter->second; // 最大频数的频数
if(a == 1 and c == 1) len = i + 1; // 对应情况 2.1
else if(b - a == 1 and d == 1) len = i + 1; // 对应情况 2.2
}
}
return len;
}
};
class Solution {
public:
int maxEqualFreq(vector<int>& nums) {
unordered_map<int, int> freq, count;
int res = 0, maxFreq = 0;
for (int i = 0; i < nums.size(); i++) {
if (count[nums[i]] > 0) {
freq[count[nums[i]]]--;
}
count[nums[i]]++;
maxFreq = max(maxFreq, count[nums[i]]);
freq[count[nums[i]]]++;
bool ok = maxFreq == 1 ||
freq[maxFreq] * maxFreq + freq[maxFreq - 1] * (maxFreq - 1) == i + 1 && freq[maxFreq] == 1 ||
freq[maxFreq] * maxFreq + 1 == i + 1 && freq[1] == 1;
if (ok) {
res = max(res, i + 1);
}
}
return res;
}
};