标签:
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.
Hint:
解题思路:
可以从Moore投票算法中得到一些启发
参考LeetCode Discuss(https://leetcode.com/discuss/43248/boyer-moore-majority-vote-algorithm-and-my-elaboration)
观察可知,数组中至多可能会有2个出现次数超过 ⌊ n/3 ⌋
的众数
记变量n1, n2为候选众数; c1, c2为它们对应的出现次数
遍历数组,记当前数字为num
若num与n1或n2相同,则将其对应的出现次数加1
否则,若c1或c2为0,则将其置为1,对应的候选众数置为num
否则,将c1与c2分别减1
最后,再统计一次候选众数在数组中出现的次数,若满足要求,则返回之。
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.
Great algorithm, but need some more explanation on the confusing word 2 "majorities". They are not necessarily be the 2 most frequent elements after the 1st round. Here is why the poster‘s 2 "majorities" algorithm really works: consider 3 cases:
1. there are no elements that appears more than n/3 times, then whatever the algorithm got from 1st round wound be rejected in the second round.
2. there are only one elements that appears more than n/3 times, after 1st round one of the candicate must be that appears more than n/3 times(<2n/3 other elements could only pair out for <n/3 times), the other candicate is not necessarily be the second most frequent but it would be rejected in 2nd round.
3. there are two elments appears more than n/3 times, candicates would contain both of them. (<n/3 other elements couldn‘t pair out any of the majorities.)
Java code:
public List<Integer> majorityElement(int[] nums) { List<Integer> result = new ArrayList<Integer>(); Integer n1 = null, n2 = null; int c1 = 0, c2 = 0; for(int i: nums){ if(n1 != null && i == n1.intValue()) { c1++; }else if(n2 != null && i == n2.intValue()){ c2++; }else if(c1 == 0) { c1 = 1; n1 = i; }else if(c2 == 0) { c2 = 1; n2 = i; }else { c1--; c2--; } } c1 = 0; c2 = 0; for(int i : nums){ if(i == n1.intValue()) { c1++; }else if( i == n2.intValue()) { c2++; } } if(c1 > nums.length/3){ result.add(n1); } if(c2 > nums.length/3) { result.add(n2); } return result; }
Reference:
1. http://bookshadow.com/weblog/2015/06/29/leetcode-majority-element-ii/
2. https://leetcode.com/discuss/43248/boyer-moore-majority-vote-algorithm-and-my-elaboration
3. http://www.programcreek.com/2014/07/leetcode-majority-element-ii-java/
标签:
原文地址:http://www.cnblogs.com/anne-vista/p/4856621.html