【LeetCode】第169题——多数元素(难度:简单)

题目描述

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 [ n/2 ] 的元素。

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

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

  2. 示例 2:
    输入: [2,2,1,1,1,2,2]
    输出: 2

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/majority-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

思路一:HashMap。用key与value记录出现过的数字与出现次数,当某个数字的出现次数大于 [ n/2 ],则返回这个数字。

思路二:Boyer-Moore 投票算法。

详细来说比较难以解释,但…以架空世界中某国大选为例吧(如有雷同,纯属巧合)。
候选人有bd和tp。选bd的人多于半数,因此答案是bd。
那么开始:
先把选举人中第一个人拉过来问一下选的谁,假设是选bd的,那么就推举bd为候选人candidate,count设置为1。然后再遍历下一个人,若选bd则count+1,若选tp则count-1,当count=0时则把下一个投票人选择的作为新的candidate并继续上述操作。
原理:若tp为当前候选人,多数派bd的选举人会阻止其当选,即count=0;若bd为当前候选人,多数派bd的选举人会保证他顺利当选,即count>0。
(不知道大家对该方法有没有稍微的理解,苦笑)
以上是LeetCode评论区大佬对于Boyer-Moore 投票算法解释(稍作魔改),真乃神人!

代码详解

思路一:HashMap

class Solution {
    public int majorityElement(int[] nums) {
        int target = nums.length / 2; // 目标是大于一半
        HashMap<Integer, Integer> hm = new HashMap<>();
        for(int i = 0; i < nums.length; ++i) {
            if(hm.containsKey(nums[i])) {	// 如果key存在就让value+1
                int val = hm.get(nums[i]) + 1;
                if(val > target) {	// 在value+1后便判断该值是否大于总数一半,即可提前终止循环,不用全部遍历完整个数组
                    return nums[i];
                } else {
                    hm.replace(nums[i], val); // 不大于一半的话就把+1后的值赋给value,并继续遍历
                }
            } else {
                hm.put(nums[i], 1);	// 如果key不存在就新添加一个key,并设定value为1
            }
        }
        return nums[0];	// 该返回值还是有点讲究的,详见下方注意点章节
    }
}

思路二:Boyer-Moore 投票算法

class Solution {
    public int majorityElement(int[] nums) {
        int count = 0;		// 思路二中的count
        int candidate = 0;	// 候选人,这里便不只是bd和tp二元对象啦
        for(int num : nums) {
            if(count == 0) { // 循环开始(或候选人更迭)
                candidate = num;
                count = 1;
            } else {
                if(num != candidate) {
                    --count;	// 当前选民选举的不是候选人时count-1
                } else {
                    ++count;	// 当前选民选举的是候选人时count+1
                }
            }
        }
        return candidate;
    }
}

注意点

  1. HashMap思路里为什么最后返回nums[0]?
    因为当nums只有一个元素时,根据循环部分的代码,只会执行一遍添加新的key,并把value置1,然后便退出循环,不会从超过一半便return的那部分代码中跳出循环。所以最后的return nums[0]是为了应对单元素数组时的情况。

  2. 还有更多思路,只不过思路一是很容易想到的,思路二是逛官方题解时发现最有意思的一个。

  3. 想对Boyer-Moore 投票算法进行深入了解的话,请做好看不懂的准备。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值