問題描述:
Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋
times.
Note: The algorithm should run in linear time and in O(1) space.
Example 1:
Input: [3,2,3] Output: [3]
Example 2:
Input: [1,1,1,3,3,2,2,2] Output: [1,2]
源碼:
這題是leetcode【169】的改進版。也是劍指offer第二版第39題的改進版。
書上的兩種方法都可以用,第一種可以先找1/3和2/3位置的值,然後判斷由這兩個點分開其三段是否滿足個數大於1/3。但是那樣略顯麻煩,所以這裏就只展示第二種了。
摩爾投票法 Moore Voting,這種方法在之前那道題Majority Element 求衆數中也使用了。題目中給了一條很重要的提示,讓我們先考慮可能會有多少個衆數。那麼有了這個信息,我們使用投票法的核心是找出兩個候選衆數進行投票,需要兩遍遍歷,第一遍歷找出兩個候選衆數,第二遍遍歷重新投票驗證這兩個候選衆數是否爲衆數即可,選候選衆數方法和前面那篇Majority Element 求衆數一樣,由於之前那題題目中限定了一定會有衆數存在,故而省略了驗證候選衆數的步驟,這道題卻沒有這種限定,即滿足要求的衆數可能不存在,所以要有驗證。代碼如下:
用num1和num2存儲候選值,count1和count2存儲他們的個數。
class Solution {
public:
vector<int> majorityElement(vector<int>& nums) {
int num1, num2, count1=0, count2=0;
for (int i=0; i<nums.size(); i++){
if (nums[i] == num1) count1++;
else if (nums[i] == num2) count2++;
else if (count1 == 0){
num1 = nums[i]; count1=1;
}
else if (count2 == 0){
num2 = nums[i]; count2=1;
}
else{
count1--; count2--;
}
}
vector<int> result;
count1 = count2 = 0;
for (int i=0; i<nums.size(); i++){
if (nums[i] == num1) count1++;
else if (nums[i] == num2) count2++;
}
if (count1 > nums.size()/3) result.push_back(num1);
if (count2 > nums.size()/3) result.push_back(num2);
return result;
}
};