Majority Element I/Majority Element II

Majority Element I

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exist in the array.

排序法

思路

将数组排序,这时候数组最中间的数肯定是众数。

public class Solution1 {
    public int majorityElement(int[] nums) {
        Arrays.sort(nums);
        return nums[nums.length / 2];
    }
}

投票法

思路

记录一个elem变量,还有一个count变量,开始遍历数组。如果新数和elem一样,那么count加上1,否则的话,如果count不是0,则count减去1,如果count已经是0,则将candidate更新为这个新的数。因为每一对不一样的数都会互相消去,最后留下来的elem就是众数。

public class Solution2 {
    public int majorityElement(int[] nums) {
        int elem=0;
        int count=0;
        for (int i=0;i<nums.length;i++){
            if (count==0){
                elem=nums[i];
                count=1;
            }else {
                if (elem==nums[i])
                    count++;
                else 
                    count--;
            }
        }
        return elem;
    }
}

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.

投票法

上一题中,超过一半的数只可能有一个,所以我们只要投票出一个数就行了。而这题中,超过n/3的数最多可能有两个,所以我们要记录出现最多的两个数。同样的两个elem和对应的两个count,如果遍历时,某个候选数和到当前数相等,则给相应计数器加1。如果两个计数器都不为0,则两个计数器都被抵消掉1。如果某个计数器为0了,则将当前数替换相应的候选数,并将计数器初始化为1。最后我们还要遍历一遍数组,确定这两个出现最多的数,是否都是众数。

public class Solution {
    public List<Integer> majorityElement(int[] nums) {
        List<Integer> result=new LinkedList<>();
        if(nums==null||nums.length==0)return result;
        int elem1=0,count1=0,elem2=0,count2=0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]==elem1){
                count1++;
            }else if(nums[i]==elem2){
                count2++;
            }else if(count1!=0&&count2!=0){
                count1--;
                count2--;
            }else{
                if(count1==0){
                    elem1=nums[i];
                    count1=1;
                }else{
                    elem2=nums[i];
                    count2=1;
                }
            }
        }
        //上面只是计算出最多的两个数,接下来计算出出现的次数是否超过n/3
        count1=0;
        count2=0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]==elem1)count1++;
            else if(nums[i]==elem2)count2++;
        }
        if(count1>nums.length/3)result.add(elem1);
        if(count2>nums.length/3)result.add(elem2);
        return result;
    }
}

推荐阅读更多精彩内容