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(具体参考:http://goo.gl/64Nams)的扩展。在找出现次数大于[n/2]的元素个数时,我们遍历两次数组,首先假设一个数为候选元素(candidate),以及与之对应的计数器count,用来统计candidate出现的次数,每次判断当前元素是否与candidate相等,如果相等则count++,否则count——,当count为0时,把当前元素设为候选元素。

candidate = 0
count = 0
for value in input:
  if count == 0:
    candidate = value
  if candidate == value:
    count += 1
  else:
    count -= 1

本题是找大于出现次数大于[n/3]的元素个数,显然这样的元素最多只有两个。于是我们便可以参考以上的思想,设置两个count和candidate。我们依然遍历两次数组。

class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {
        vector<int>ans;
        int count1=0,count2=0,candidate1=0,candidate2=1;
        for(int n: nums){
            if(n==candidate1)count1++;
            else if(n==candidate2)count2++;
            else if(count1==0){
                candidate1=n;
                count1=1;
            }
            else if(count2==0){
                candidate2=n;
                count2=1;
            }
            else {
                count1--;
                count2--;
            }
        }
        count1=count2=0;
        for(int n: nums){
            if(n==candidate1)count1++;
            else if(n==candidate2)count2++;
        }
        if(count1>nums.size()/3)ans.push_back(candidate1);
        if(count2>nums.size()/3)ans.push_back(candidate2);
        return ans;
    }
};

再扩展下,如果要找出现的次数大于[n/k]的元素的个数,我们就设置k-1个计数器和k-1个候选元素。

public class Solution {
    public List<Integer> majorityElement(int[] nums) {
        int n = nums.length, k = 3;  //in this question, k=3 specifically
        List<Integer> result = new ArrayList<Integer>();
        if (n==0 || k<2) return result;
        int[] candidates = new int[k-1];
        int[] counts = new int[k-1];
        for (int num: nums) {
            boolean settled = false;
            for (int i=0; i<k-1; i++) {
                if (candidates[i]==num) {
                    counts[i]++;
                    settled = true;
                    break;
                } 
            }
            if (settled) continue;
            for (int i=0; i<k-1; i++) {
                if (counts[i]==0) {
                    counts[i] = 1;
                    candidates[i] = num;
                    settled = true;
                    break;
                } 
            }
            if (settled) continue;
            for (int i=0; i<k-1; i++) counts[i] = (counts[i] > 0) ? (counts[i]-1) : 0;
        }
        Arrays.fill(counts, 0);
        for (int num: nums) {
            for (int i=0;i<k-1; i++) {
                if (candidates[i]==num) {
                    counts[i]++;
                    break;
                }
            }
        }
        for (int i=0; i<k-1; i++) if (counts[i]>n/k) result.add(candidates[i]);
        return result;
    }
}

 

posted @ 2017-03-20 12:09  Tsunami_lj  阅读(120)  评论(0编辑  收藏  举报