229. 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.

 

Boyer-Moore Majority Vote algorithm

The essential concepts is you keep a counter for the majority number X. If you find a number Y that 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.

 public List<Integer> majorityElement(int[] nums) {
       List<Integer> list = new ArrayList<>();
       if (nums == null || nums.length == 0) {
           return list;
       }
       if (nums.length == 1) {
           list.add(nums[0]);
           return list;
       }
       int ans1 = 0, ans2 = 0;
       int count1 = 0, count2 = 0;
       for (int i = 0; i < nums.length; i++) {
           if (nums[i] != ans1 && nums[i] != ans2) {
               if (count1 == 0) {
                   ans1 = nums[i];
                   count1++;
               } else if (count2 == 0) {
                   ans2 = nums[i];
                   count2++;
               } else {
                   count1--;
                   count2--;
               }
           } else if (nums[i] == ans1) {
               count1++;
           } else {
               count2++;
           }
       }
       count1 = 0;
       count2 = 0;
       
       for (int i : nums) {
           if (i == ans1) {
               count1++;
           } else if (i == ans2) {
               count2++;
           }
       }
       if (count1 > nums.length / 3) {
           list.add(ans1);
       }
       if (count2 > nums.length / 3) {
           list.add(ans2);
       }
       return list;
}

多个候选人的投票,从0开始计票, 因为每一票都要计算count, follow up 延伸到找K个 这样的数: 

simple method is to pick all elements one by one. For every picked element, count its occurrences by traversing the array, if count becomes more than n/k, then print the element. Time Complexity of this method would be O(n2).

A better solution is to use sorting. First, sort all elements using a O(nLogn) algorithm. Once the array is sorted, we can find all required elements in a linear scan of array. So overall time complexity of this method is O(nLogn) + O(n) which is O(nLogn).

simple method is to pick all elements one by one. For every picked element, count its occurrences by traversing the array, if count becomes more than n/k, then print the element. Time Complexity of this method would be O(n2).

A better solution is to use sorting. First, sort all elements using a O(nLogn) algorithm. Once the array is sorted, we can find all required elements in a linear scan of array. So overall time complexity of this method is O(nLogn) + O(n) which is O(nLogn).

  

 

posted @ 2017-08-07 09:08  apanda009  阅读(138)  评论(0编辑  收藏  举报