问题描述:
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;
}
};