剑指 Offer 39. 数组中出现次数超过一半的数字

剑指 Offer 39. 数组中出现次数超过一半的数字

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

你可以假设数组是非空的,并且给定的数组总是存在多数元素

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

思路1:直接排序,然后返回中间索引位置的元素即可,如果调用API的话,只要两行代码,建议可以自己实现快排。

class Solution {
    public int majorityElement(int[] nums) {
        quickSort(nums,0,nums.length - 1);
        return nums[nums.length / 2];   
    }

    public void quickSort(int[] nums,int left,int right){
        if(left > right) return;
        int i = left;
        int j = right;
        while(i < j){
            // 分别找到小于基准的值 和 大于基准的值 进行交换
            while(i < j && nums[j] >= nums[left]) j--;
            while(i < j && nums[i] <= nums[left]) i++;
            swap(nums,i,j);
        }
        // 把基准放到中间
        swap(nums,i,left);
        quickSort(nums,left,i-1);
        quickSort(nums,i+1,right);

    }

    public void swap(int[] nums,int l,int r){
        int temp = nums[l];
        nums[l] = nums[r];
        nums[r] = temp;

    }
}
由于此题的相同元素太多,用快排其实效率并不是很高,重在实现快排。

思路2:摩尔投票法,参考少数服从多数机制。举个例子,有5个人投1,2个人投2,2个人投3。那么我们可以将4个不投1的和5个投1的进行抵消,最后剩下一个投1的。由于本题给定的数组一定存在多数元素,所以并不用考虑会出现一样多的元素个数。

class Solution {
    public int majorityElement(int[] nums) {
       // 摩尔投票法
       // 记录当前最多票是什么 以及 最多票抵消后的票数
       int result = nums[0];
       int sum = 1;
       for(int i = 1;i<nums.length;i++){
           // 如果下一票和最多票不一样
           if(nums[i] != result){
               // 票数不为0 更新sum
               if(sum != 0){
                   sum--;
               // 票数为0 更新result以及sum
               }else{
                   result = nums[i];
                   sum++;
               }
           // 票一样 直接更新sum
           }else{
               sum++;
           }
       } 
       return result;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值