229. Majority Element II

https://leetcode.com/problems/majority-element-ii/

  本题大意:给定一个大小为n的正整数数组,求出出现了超过⌊ n/3 ⌋次的元素。要求时间复杂度为o(n),空间复杂度为o(1)。

  解题思路:首先要清楚,满足条件的这种元素最多有几个?答案应该是2个。所以我们只需要用两个变量(m1/m2)来存储这两个潜在的元素,用两个变量(c1/c2)来存储他们出现的次数。这就解决了空间复杂度的问题。

  其次,我们参考Majority Element的思路,只不过这里要更新的是两个值。什么时候更新c1和c2?遇到m1,c1就加1,否则减1;遇到m2,c2就加1,否则就减1。什么时候更新m1和m2?当c1和c2减到0的时候就改变m1和m2的值,同时将c1和c2的值置为1。

  这里有一个问题,是不是说最终剩下的那两个m1和m2一定是要求得的答案呢?答案是否定的。最坏的情况,即所有元素都不相同时,最终也会得到这样的m1和m2,但是显然m1和m2并不是我们想要的结果。所以距离成功还需要一步:统计这两个值出现的次数。

  最后,统计m1和m2出现的次数,如果满足大于⌊ n/3 ⌋,那么就是我们期待的结果。

代码如下:

 1 class Solution {
 2 public:
 3     vector<int> majorityElement(vector<int>& nums) {
 4         vector<int> v;
 5         int n = nums.size();
 6         if(n == 0) return v;
 7         if(n == 1) {v.push_back(nums[0]);return v;}
 8         int m1 = nums[0];
 9         int m2 = 0;
10         int c1 = 0;
11         int c2 = 0;
12         for(int i = 0; i < n; i++)
13         {
14             if(nums[i] == m1) ++c1;
15             else if(nums[i] == m2) ++c2;
16             else if(c1 == 0){++c1; m1 = nums[i];}
17             else if(c2 == 0){++c2; m2 = nums[i];}
18             else{--c1; --c2;}
19         }
20         c1 = 0;
21         c2 = 0;
22         for(int i = 0; i < n; i++)
23         {
24             if(nums[i] == m1)
25                 ++c1;
26             if(nums[i] == m2)
27                 ++c2;
28         }
29         if(c1 > n/3)
30             v.push_back(m1);
31         if(m2 != m1 && c2 > n/3)
32             v.push_back(m2);
33         return v;
34 
35     }
36 };
原文地址:https://www.cnblogs.com/jingyuewutong/p/5584704.html