Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋
times. The algorithm should run in linear time and in O(1) space.
网络上的思路参考:
Find k different element, and "remove" them as a group, the remaining element must be the element that appears more than
⌊n/k⌋ times. 至多有k-1个出现次数超过⌊ n/k ⌋的元素:至多有1个出现次数超过⌊ n/2 ⌋,至多有2个出现次数超过⌊ n/3 ⌋...
For those who aren't familiar with Boyer-Moore Majority Vote algorithm, I found a great article
(http://goo.gl/64Nams) that helps me to understand this fantastic algorithm!! Please check it out!
The essential concepts is you keep a counter for the majority number X. If you find a number Ythat is not X, the current counter should deduce 1. The reason is that if there is 5 X and 4 Y, there would be one (5-4) more X than Y. This could be explained as "4 X being paired out by 4 Y".
And since the requirement is finding the majority for more than ceiling of [n/3], the answer would be less than or
equal to two numbers. So we can modify the algorithm to maintain two counters for two majorities.
观察可知,数组中至多可能会有2个出现次数超过 ⌊ n/3 ⌋
的众数
记变量n1, n2为候选众数; c1, c2为它们对应的出现次数
遍历数组,记当前数字为num
若num与n1或n2相同,则将其对应的出现次数加1
否则,若c1或c2为0,则将其置为1,对应的候选众数置为num
否则,将c1与c2分别减1
最后,再统计一次候选众数在数组中出现的次数,若满足要求,则返回之。
class Solution
{
public:
vector<int> majorityElement(vector<int> &a)
{
int y = 0, z = 1, cy = 0, cz = 0;
for (auto x: a)
{
if (x == y) cy++;
else if (x == z) cz++;
else if (! cy) y = x, cy = 1;//仔细分析,确实很有道理,假设其中一个候选众数占了1/3(遇到众数,其
他操作就可以忽略,请看!!!这些代码都是独立的,一次只能选择一条执行路径),那么另外一个候选众数(假如有)则占了
剩下的元素的一半以上!!
else if (! cz) z = x, cz = 1;
else cy--, cz--;
}
cy = cz = 0;
for (auto x: a) if (x == y) cy++;
else if (x == z) cz++;
vector<int> r;
if (cy > a.size()/3) r.push_back(y);
if (cz > a.size()/3) r.push_back(z);
return r;
}
};
来看我自己的实现代码:
1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 5 6 class Solution { 7 public: 8 vector<int> majorityElement(vector<int>& nums) { 9 vector<int>res; 10 int mode1=INT_MAX, mode2=INT_MIN,cn1=0,cn2=0; 11 for(auto x:nums) 12 { 13 if (x == mode1)cn1++; 14 else if (x == mode2)cn2++; 15 else if (!cn1)mode1 = x, cn1 = 1; 16 else if (!cn2)mode2 = x, cn2 = 1; 17 else cn1--, cn2--; 18 } 19 cn1 = 0, cn2 = 0; 20 for (auto x :nums) 21 { 22 if (x == mode1)cn1++; 23 if (x == mode2)cn2++; 24 } 25 if (cn1 > nums.size() / 3)res.push_back(mode1); 26 if (cn2 > nums.size() / 3)res.push_back(mode2); 27 return res; 28 } 29 }; 30 int main() 31 { 32 Solution test; 33 vector<int> val = {3};//{ 2, 3, 5, 3, 2, 3,2,5}; 34 vector<int>result = test.majorityElement(val); 35 for each(auto x in result) 36 cout << x << " "; 37 return 0; 38 }