#leetcode#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.

Hint:

  1. How many majority elements could it possibly have?

学习了曹神的思路:http://meetqun.com/thread-10186-1-1.html

找出出现次数严格大于[n/3]的数。* S: y/ B6 W# _* y# r
分析: 简单题。这种数最多有两个。其实我们每次扔掉3个不同的数,结果是不变的——就像众数的推广。" j8 m5 s* D* x6 {. l; C; k. y
如何扔掉3个不同的数?0 d, L2 n7 R4 W
用两个“槽”保存两个不同的数,遍历所有的数,如果和槽里的数相等,则计数器增加1。否则把两个槽里的数和这个数一起扔掉,正好是3个不同的数。
注意槽可能为空(计数器为0),最后两个槽里的数(如果有)就是可能的候选。我们再数一下分别出现了多少次,看看是否能达到要求。因为只有两个候选,数一下时间也是O(n)的。, P/ j3 @% g6 l4 A) T' m$ ~
总体时间复杂度是O(n)的,空间复杂度是O(1)的。关键在于对空槽的处理——不过最后数的时候,无论空不空我都数了,这没关系……

public class Solution {
    public List<Integer> majorityElement(int[] nums) {
        int num1 = 0;
        int num2 = 0;
        int count1 = 0;
        int count2 = 0;
        
        for(int num : nums){
            if(num == num1){
                count1++;
            }else if(num == num2){
                count2++;
            }else if(count1 == 0){
                num1 = num;
                count1 = 1;
            }else if(count2 == 0){
                num2 = num;
                count2 = 1;
            }else{
                count1--;
                count2--;
            }
        }
        count1 = 0;
        count2 = 0;
        for(int i : nums){
            if(i == num1){
                count1++;
            }else if(i == num2){
                count2++;
            }
        }
        
        List<Integer> res = new ArrayList<Integer>();
        if(count1 > nums.length / 3){
            res.add(num1);
        }
        if(count2 > nums.length / 3){
            res.add(num2);
        }
        
        return res;
    }
}



你可能感兴趣的:(LeetCode)