#169 Majority Element

Description

Given an array nums of size n, return the majority element.

The majority element is the element that appears more than ⌊n / 2⌋ times. You may assume that the majority element always exists in the array.

Examples

Example 1:

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

Example 2:

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

Constraints:

n == nums.length
1 <= n <= 5 * 1 0 4 10^4 104
− 1 0 9 -10^9 109 <= nums[i] <= 1 0 9 10^9 109

Follow-up: Could you solve the problem in linear time and in O(1) space?

思路

虽然这题只是easy,但还是有几种不同的方式来处理。以下所有处理方式都基于 “majority number的数量超过数组数量的一半”

排序

最开始也是最简单的方法,就是对数组进行排序,由于majority数量超过数组数量的一半,所以直接查找排序后的中点即可。

MAP

通过map存储每个数字的数量,一旦这个数量超过一半,就退出循环,认为这个数是majority number

二分查找

我们对一个序列,递归的搜索他左半边和右半边的majority number,对以下两重情况进行分别处理

  • majority左 = = = majority右 → majority确定
  • majority左 ≠ \neq = majority右 → 分别计算majority左和majority右在序列中的数量,选择数量多的作为该序列的majority

Boyer-Moore Voting

这个solution里面看到的,他用了一个很tricky的方法,既然majority的数量一定是 > half 的,那我们假设[0]为majority,count的数量为1,然后依次对序列中的每个单词进行判断

  • count == 0? 重置当前num为majority
  • count != 0?
    • 当前num == majority → count++
    • 当前num != majority → count–

到最后剩下的majority就是majority,取一种最极端的情况

  • 前 n/2+1 都是majority,那到最后 count=1,majority=[0]

其他情况下,由于count(majority) > half,都会导致最后剩下的是majortiy

代码

排序

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

MAP

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

二分查找

class Solution {
    private int countInRange(int[] nums, int num, int lo, int hi) {
        int count = 0;
        for (int i = lo; i <= hi; i++) {
            if (nums[i] == num) {
                count++;
            }
        }
        return count;
    }

    private int majorityElementRec(int[] nums, int lo, int hi) {
        // base case; the only element in an array of size 1 is the majority
        // element.
        if (lo == hi) {
            return nums[lo];
        }

        // recurse on left and right halves of this slice.
        int mid = (hi-lo)/2 + lo;
        int left = majorityElementRec(nums, lo, mid);
        int right = majorityElementRec(nums, mid+1, hi);

        // if the two halves agree on the majority element, return it.
        if (left == right) {
            return left;
        }

        // otherwise, count each element and return the "winner".
        int leftCount = countInRange(nums, left, lo, hi);
        int rightCount = countInRange(nums, right, lo, hi);

        return leftCount > rightCount ? left : right;
    }

    public int majorityElement(int[] nums) {
        return majorityElementRec(nums, 0, nums.length-1);
    }
}

Boyer-Moore Voting

class Solution {
    public int majorityElement(int[] nums) {
        int count = 0;
        Integer candidate = null;

        for (int num : nums) {
            if (count == 0) {
                candidate = num;
            }
            count += (num == candidate) ? 1 : -1;
        }

        return candidate;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值