LeetCode 169. Majority Element

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.

Example 1:

Input: [3,2,3]
Output: 3

Example 2:

Input: [2,2,1,1,1,2,2]
Output: 2

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

方法一:排序

这种最容易理解,直接调用java库函数进行快速排序,时间复杂度为O(NlgN)

为什么排序完之后直接取 nums[nums.length/2] 呢?

由于majority的定义是: 出现次数大于⌊ n/2 ⌋ 次

排序完毕之后,若majority元素不经过索引为 nums.length/2的位置,那么这个数是放不下的 。因为索引[0,nums.length/2-1] 的闭区间内只有num.length/2个元素。而另一边,[nums.length/2+1,nums.length-1] 的闭区间内只有 num.length/2 - 1 个元素。两边都放不下majortiy的全部元素。

代码十分简单:

import java.util.Arrays;
class Solution {
    public int majorityElement(int[] nums) {
        Arrays.sort(nums);
        return nums[nums.length/2];
    }
}

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

第二种解法:摩尔投票法

之前在耍剑指offer的时候见过,当时只是有个印象,没有深究。

摩尔投票法的核心思想是互相抵消。majority出现次数大于nums.length/2,因此在抵消过程中最终能生存下来。

其实可以将每个数字看作一个部队。现在有一个竞技场,每次进来一个士兵。第一个士兵进去之后,占领了这个竞技场,第二个进来的士兵如果和第一个进来的士兵是同一个部队,则两人占领竞技场,如果是不同部队,则两人同归于尽!第三个人进来继续占领竞技场.....以此类推,直到所有士兵都上过擂台。

其实有点像古代的打擂台,只是此时上来的除了挑战者,还有可能是队友~

最终留在竞技场上的某个士兵(或者同一个部队的士兵们)所在的队伍即为获胜队伍。事实上,这场比赛完全是比人数,获胜的部队一定是人数最多的部队,与上擂台的顺序无关。获胜的队伍就是问题中的众数~

举个例子:

Input: [2,2,1,1,1,2,2]
Output: 2

可以根据代码自行代入,查看过程。注意continue的使用

import java.util.Arrays;
class Solution {
    public int majorityElement(int[] nums) {
        int count_maj = 1;
        int maj = nums[0];
        for(int i = 1;i<nums.length;i++){
            if(count_maj==0){
                count_maj = 1;
                maj = nums[i];
                continue;
            }
            if(nums[i]==maj){
                count_maj++;
            }
            else{
                count_maj--;
            }
        }
        return maj;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值