169. 求众数

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

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

示例 1:

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

输入: [2,2,1,1,1,2,2]
输出: 2

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

1.暴力算法的思路是遍历每个元素出现的次数,用到两层遍历,如果出现的次数大于n/2,就返回.

2.hashMap的思路和前面一到链表的类似,key用来存数,value用来存出现的次数. 最后再通过一个方法遍历map里的value最大的返回.

3.排序, 先把数组排序,因为题中给的条件是众数,数量大于数组长度的一半,那么排序后下标为n/2的位置上肯定是众数.

4.Boyer-Moore 投票算法.如果我们把众数记为 +1 ,把其他数记为 −1 ,将它们全部加起来,显然和大于 0 ,从结果本身我们可以看出众数比其他数多。具体的实现是维护一个计数器,把第一个数当作众数开始遍历,遇到众数计数器+1,否则就-1,当计数器等于零,我们就放弃当前众数候选人并忘记之前的计数(这个思路和之前一个赌徒心理的题类似,那个题是如果今天之前的是负数就忘记输掉的钱继续赌,如果今天之前的钱是正的,就拿着这些钱继续赌),让下个数字当众数的候选人,因为众数的数量大于数组的一半,并且我们当计数器等于0的时候忘记的肯定是成对的:一个众数一个非众数,所以如果最终的计数器大于0,那这个众数的候选者就是我们要的众数,不会出现漏掉候选人的情况.

总结:算法的相对最优解大多要充分利用到题中所给条件,本题的众数的数量大于数组的一半就是一个条件,对比暴力算法,排序算法和投票算法要优雅的多.

2.class Solution {
private Map<Integer, Integer> countNums(int[] nums) {
Map<Integer, Integer> counts = new HashMap<Integer, Integer>();
for (int num : nums) {
if (!counts.containsKey(num)) {
counts.put(num, 1);
}
else {
counts.put(num, counts.get(num)+1);
}
}
return counts;
}

public int majorityElement(int[] nums) {
    Map<Integer, Integer> counts = countNums(nums);

    Map.E***y<Integer, Integer> majorityE***y = null;
    for (Map.E***y<Integer, Integer> e***y : counts.e***ySet()) {
        if (majorityE***y == null || e***y.getValue() > majorityE***y.getValue()) {
            majorityE***y = e***y;
        }
    }

    return majorityE***y.getKey();
}

}

作者:LeetCode
链接:https://leetcode-cn.com/problems/majority-element/solution/qiu-zhong-shu-by-leetcode-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

4.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;
}

作者:LeetCode
链接:https://leetcode-cn.com/problems/majority-element/solution/qiu-zhong-shu-by-leetcode-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值