剑指offer_28:数组中出现次数超过一半的数字

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2

限制:
1 <= 数组长度 <= 50000

1、数组排序

//自带的方法
//时间复杂度:O(nlogn)
//空间复杂度:O(nlogn)
class Solution {
    public int majorityElement(int[] nums) {
        Arrays.sort(nums);
        return nums[nums.length/2];
    }
}
//堆排序
//时间复杂度:O(nlogn)
//空间复杂度:O(1)
class Solution {
    public int majorityElement(int[] nums) {
        heapSort(nums);
        return nums[nums.length/2];
    }
    public void heapSort(int[] a){
        for(int i=(a.length-1)/2;i>=0;i--){
            adjustHeap(a,i,a.length);
        }
        for (int i=a.length-1;i>=1;i--){
            swap(a,0,i);
            adjustHeap(a,0,i);
        }
    }
    public void adjustHeap(int[] a,int index,int size){
        while (2*index+1<size){
            int j=2*index+1;
            if(j+1<size&&a[j]<a[j+1]) j++;
            if(a[index]<a[j]) {
                swap(a, index, j);
            }else {
                break;
            }
            index=j;
        }
    }
    public void swap(int[] n,int a,int b){
        int temp=n[a];
        n[a]=n[b];
        n[b]=temp;
    }
}

2、Hash

class Solution {
    public int majorityElement(int[] nums) {
        Map<Integer,Integer> map=new HashMap<>();
        int len=nums.length/2;
        for(int num:nums){
            map.put(num,map.getOrDefault(num,0)+1);
            if(map.get(num)>len){
                return num;
            }
        }
        return 0;
    }
}

3、摩尔投票算法

摩尔投票算法很巧妙。从序列中选择两个不相同的数字删掉,最后留下来的就是众数。

class Solution {
    public int majorityElement(int[] nums) {
        int sum=0;
        int now=nums[0];
        for(int i=0;i<nums.length;i++){
            if(sum==0){
                now=nums[i];
            }
            if(now==nums[i]){
                sum++;
            }else{
                sum--;
            }
        }
        return now;
    }
}
posted @ 2021-01-23 18:37  小昊子丫  阅读(48)  评论(0编辑  收藏  举报