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
思路
- 讀題
前綴: 前n個元素
符合條件: 元素頻次都相同, 只有一個不同
找規律
四種情況:
- 數字有兩種分類, 第一類頻次相等, 第二類比第一類頻次多1, 並且第二類只有一個數字 --> [1,1,1,2,2,3,3]
- 數字有兩種分類, 第一類頻次相等, 第二類頻次為1, 並且第二類只有一個數字 --> [1,1,2,2,3]
- 數字只有一類, 全重復 --> [1,1,1,1]
- 數字只有一類, 全不重復 --> [1,2,3,4]
記錄下數字出現頻次和出現頻次的出現頻次
- 示例: nums = [2,2,1,1,5,3,3,5]
代碼實現
找規律 多情況分析
class Solution {
/**
* 數據量最大界限
*/
private final static int SIZE = (int) 1e5 + 50;
public int maxEqualFreq(int[] nums) {
// freq of number 出現數字的頻次
int[] freqOfNum = new int[SIZE];
// freq of number's freq 出現數字頻次的頻次
int[] freqOfFreq = new int[SIZE];
// maxFreq 數字出現頻次的最大值
int maxFreq = Integer.MIN_VALUE, ans = 0;
/*
* 四種情況:
* 1. 數字有兩種分類, 第一類頻次相等, 第二類比第一類頻次多1, 並且第二類只有一個數字 --> [1,1,1,2,2,3,3]
* 2. 數字有兩種分類, 第一類頻次相等, 第二類頻次為1, 並且第二類只有一個數字 --> [1,1,2,2,3]
* 3. 數字只有一類, 全重復 --> [1,1,1,1]
* 4. 數字只有一類, 全不重復 --> [1,2,3,4]
*/
for (int i = 0; i < nums.length; i++) {
freqOfNum[nums[i]]++;
freqOfFreq[freqOfNum[nums[i]]]++;
maxFreq = Math.max(freqOfNum[nums[i]], maxFreq);
// 第一種情況: 最高頻次maxFreq出現數為1, 並且次高頻次(maxFreq-1)出現數*其頻次==i
// --> [1,1,1,2,2,3,3] --> {maxFreq:3(1), fof[2]:3, fof[3]:1, i:6}
boolean one = (freqOfFreq[maxFreq] == 1) && (freqOfFreq[maxFreq - 1] * (maxFreq - 1) + 1 == i + 1);
// 第二種情況: 最高頻次maxFreq出現數*其頻次==i
// --> [1,1,2,2,3] --> {maxFreq:2, fof[2]:2, i=4}
boolean two = freqOfFreq[maxFreq] * maxFreq + 1 == i + 1;
// 第三種情況: 最高頻次maxFreq出現數==1 --> [1,1,1,1] --> {maxFreq:4, fof[4]:1}
// 與第一種情況合並
boolean thr = freqOfFreq[maxFreq] == 1;
if (one || two) {
ans = i + 1;
}
}
// 第四種情況: 最高頻次maxFreq==1 --> [1,2,3,4] --> {maxFreq:1, fof[1]:4}
boolean four = maxFreq == 1;
if (four) {
return nums.length;
}
return ans;
}
}
參考資源
第 157 場周賽 全球排名
java題解,讓一眼就看懂的算法!算是對 @楊添倫 算法的補充
C++,O(n),考慮四種情況