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

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

示例 1:

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

限制:

1 <= 数组长度 <= 50000

一、摩尔算法

具体摩尔算法,我借鉴一下大神的解释更好理解点。

为什么答案能写那么长呢。。。核心就是对拼消耗。玩一个诸侯争霸的游戏,假设你方人口超过总人口一半以上,并且能保证每个人口出去干仗都能一对一同归于尽。最后还有人活下来的国家就是胜利。那就大混战呗,最差所有人都联合起来对付你(对应你每次选择作为计数器的数都是众数),或者其他国家也会相互攻击(会选择其他数作为计数器的数),但是只要你们不要内斗,最后肯定你赢。最后能剩下的必定是自己人。

  1. class Solution {
  2. public int majorityElement(int[] nums) {
  3. int vote = 0, x = 0;
  4. for (int num : nums) {
  5. if (vote == 0) x =num;
  6. vote += num == x ? 1 : -1;
  7. }
  8. return x;
  9. }
  10. /*
  11. x=num=1
  12. vote=1
  13. x = 2
  14. vote = 0
  15. x =3 vote=1
  16. vote = 0
  17. x = num =2 vote =1
  18. */
  19. }

除了这个,由于题目要求给定的数组总是存在多数元素,所以需要加入“验证环节”,所以借鉴了K神的思路,遍历数组统计x的量,如果大于num.length/2,则x是众数,否则反正。

  1. class Solution {
  2. public int majorityElement(int[] nums) {
  3. int vote = 0, x = 0, count = 0;
  4. for (int num : nums) {
  5. if (vote == 0) x =num;
  6. vote += num == x ? 1 : -1;
  7. }
  8. for (int num : nums)
  9. if (num == x) count++;
  10. return count > nums.length/2 ? x : 0;
  11. }
  12. }

二、哈希

  1. class Solution {
  2. /*
  3. 用HashMap统计num的数量,即可找出众数
  4. */
  5. public Map<Integer,Integer> map(int[] nums) {
  6. Map<Integer,Integer> map = new HashMap<Integer, Integer>();
  7. for (int num : nums) {
  8. if (!map.containsKey(num)) {
  9. map.put(num, 1);
  10. } else {
  11. map.put(num,map.get(num) + 1);
  12. }
  13. }
  14. return map;
  15. }
  16. public int majorityElement(int[] nums) {
  17. Map<Integer, Integer> map = map(nums);
  18. Map.Entry<Integer,Integer> majorityElement = null;
  19. for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
  20. if (majorityElement == null || entry.getValue() > majorityElement.getValue()) {
  21. majorityElement = entry;
  22. }
  23. }
  24. return majorityElement.getKey();
  25. }
  26. }

三、数组排序

  1. class Solution {
  2. /*
  3. 用数组nums进行排序
  4. */
  5. public int majorityElement(int[] nums) {
  6. Arrays.sort(nums);
  7. return nums[nums.length / 2];
  8. }
  9. }

参考链接:

1)https://www.zhihu.com/question/49973163/answer/617122734

2)剑指 Offer 39. 数组中出现次数超过一半的数字(摩尔投票法,清晰图解) – 数组中出现次数超过一半的数字 – 力扣(LeetCode) (leetcode-cn.com)

版权声明:本文为RainsX原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/RainsX/p/15125987.html