LeetCode 169.多数元素

169.多数元素

在这里插入图片描述

思路一:

适用哈希映射(HashMap)来实现,key表示数组的元素,value表示各元素出现的次数,然后找到出现次数最大的一个或者,找到第一次超过n/2次的元素。

class Solution {
    public int majorityElement(int[] nums) {
        int mid = nums.length / 2;
        Map<Integer, Integer> count = new HashMap<>();
        for (int num : nums) {
            if (count.containsKey(num)) {
                if (count.get(num) + 1 > mid) {
                    return num;
                } else {
                    count.put(num, count.get(num) + 1);
                }
            } else {
                count.put(num, 1);
            }
        }
        for (int num : count.keySet()) {
            return num;
        }
        return 0;
    }
}
思路二:

因为考虑到多数元素的定义是出现次数超过n/2次的元素,那么考虑排序后取n/2下标的值就是多数元素;

假如长度为奇数的数组(例如7),出现次数大于n/2(例如3.5,即最少出现4次)的元素,那么排序后位于中间位置(4)元素肯定是属于那个最多的。

假如长度为偶数的数组(例如6),出现次数大于n/2(例如3,即最少出现4次)的元素,那么排序后位于第3、4都应该是最大的,所以取第3、4都可以。

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

适用java的排序,使用的是双轴快速排序;

考虑到我们取的是中间位置的数,那么可以采用快速排序,然后根据每次分割后的下标

若下标刚好是中间位置,那么就是这个数为众数;

后面的排序只需要排中间位置存在的的那一个分组

这样就不用全部排序;

class Solution {
    public int majorityElement(int[] nums) {
        return quickSort(nums, 0, nums.length - 1, nums.length / 2);
    }
    private int quickSort(int[] nums, int low, int high, int mid) {
        int index = getIndex(nums, low, high);
        if (index == mid) {
            return nums[mid];
        }
        if (index > mid) {
            return quickSort(nums, low, index - 1, mid);
        } else {
            return quickSort(nums, index + 1, high, mid);
        }
    }

    private int getIndex(int[] nums, int low, int high) {
        int temp = nums[low];
        int i = low;
        int j = high;
        while (i != j) {
            while (nums[j] >= temp && i < j)
                j--;
            //再找右边的
            while (nums[i] <= temp && i < j)
                i++;
            //交换两个数在数组中的位置
            if (i < j) {
                int t = nums[i];
                nums[i] = nums[j];
                nums[j] = t;
            }
        }
        //最终将基准数归位
        nums[low] = nums[i];
        nums[i] = temp;
        return i;
    }
}
思路三:

在解题思路中找到的方法—Boyer-Moore 算法:

  • Boyer-Moore 算法
    • 维护一个候选众数 candidate 和它出现的次数 count。初始时 candidate 可以为任意值,count 为 0;
    • 遍历数组中的所有元素,对于每个元素 x
      • 在判断 x 之前,如果 count 的值为 0,我们先将 x 的值赋予 candidate,随后我们判断 x:
      • 如果 x 与 candidate 相等,那么计数器 count 的值增加 1;
      • 如果 x 与 candidate 不等,那么计数器 count 的值减少 1。
    • 在遍历完成后,candidate 即为整个数组的众数。
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、付费专栏及课程。

余额充值