number which appears more than n/3 times in an array
Jan Dvorak's answer is probably best:
- Start with two empty candidate slots and two counters set to 0.
- for each item:
- if it is equal to either candidate, increment the corresponding count
- else if there is an empty slot (i.e. a slot with count 0), put it in that slot and set the count to 1
- else reduce both counters by 1
At the end, make a second pass over the array to check whether the candidates really do have the required count. This isn't allowed by the question you link to but I don't see how to avoid it for this modified version. If there is a value that occurs more than n/3 times then it will be in a slot, but you don't know which one it is.
If this modified version of the question guaranteed that there were two values with more than n/3
elements (in general, k-1
values with more than n/k
) then we wouldn't need the second pass. But when the original question has k=2
and 1 guaranteed majority there's no way to know whether we "should" generalize it as guaranteeing 1 such element or guaranteeing k-1
. The stronger the guarantee, the easier the problem.
Using Boyer-Moore Majority Vote Algorithm, we get:
vector<int> majorityElement(vector<int>& nums) {
int cnt1=0, cnt2=0;
int a,b;
for(int n: A){
if (n == a) cnt1++;
else if (n == b) cnt2++;
else if (cnt1 == 0){
cnt1++;
a = n;
}
else if (cnt2 == 0){
cnt2++;
b = n;
}
else{
cnt1--;
cnt2--;
}
}
cnt1=cnt2=0;
for(int n: nums){
if (n==a) cnt1++;
else if (n==b) cnt2++;
}
vector<int> result;
if (cnt1 > nums.size()/3) result.push_back(a);
if (cnt2 > nums.size()/3) result.push_back(b);
return result;
}
Updated, correction from @Vipul Jain