棋子

导航

Majority Element II

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 }

 

posted on 2015-08-20 15:01  鼬与轮回  阅读(184)  评论(0编辑  收藏  举报