169.多数元素- 力扣(LeetCode)

题目:

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

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

示例 1:

输入:nums = [3,2,3]

输出:3

示例 2:

输入:nums = [2,2,1,1,1,2,2]

输出:2

提示:

  • n == nums.length

  • 1 <= n <= 5 * 104

  • -109 <= nums[i] <= 109

思路如下:
  1. 哈希表统计法: 遍历数组 nums ,用 HashMap 统计各数字的数量,即可找出 众数 。此方法时间和空间复杂度均为 O(N) 。

  2. 数组排序法: 将数组 nums 排序,数组中点的元素 一定为众数。

  3. 摩尔投票法: 核心理念为 票数正负抵消 。此方法时间和空间复杂度分别为 O(N) 和 O(1) ,为本题的最佳解法。

题解如下:
#1
class Solution:
    def majorityElement(self, nums):
        """
                  :type:  nums: List[int]
                  :rtype: int
        """
        count = {}
        m = len(nums) // 2
        for i in range(len(nums)):
            if nums[i] not in count:
                count[nums[i]] = 1
            else:
                count[nums[i]] += 1
        
        for key in count:
            if count[key] > m:
                return key
#2
class Solution:
    def majorityElement(self, nums):
        """
                  :type:  nums: List[int]
                  :rtype: int
        """
        nums.sort()          # 时间复杂度 O(n log n)
        return nums[len(nums) // 2]
#3
class Solution:
    def majorityElement(self, nums):
        """
                  :type:  nums: List[int]
                  :rtype: int
        """
        votes = 0
        for num in nums:
            if votes == 0: x = num
            votes += 1 if num == x else -1
        return x
        """
        考虑数组不存在众数的情况,需要加入一个 “验证环节” ,遍历数组 nums 统计 x 的数量。
        """
        # 验证 x 是否为众数
        for num in nums:
            if num == x: count += 1
        return x if count > len(nums) // 2 else 0 # 当无众数时返回 0
摩尔投票:

设输入数组 nums 的众数为 x ,数组长度为 n 。

推论一: 若记 众数 的票数为 +1 ,非众数 的票数为 −1 ,则一定有所有数字的 票数和 >0 。

推论二: 若数组的前 a 个数字的 票数和 =0 ,则 数组剩余 (n−a) 个数字的 票数和一定仍 >0 ,即后 (n−a) 个数字的 众数仍为 x 。

根据以上推论,记数组首个元素为 n1,众数为 x ,遍历并统计票数。当发生 票数和 =0 时,剩余数组的众数一定不变 ,这是由于:

  • 当 n1 = x : 抵消的所有数字中,有一半是众数 x 。

  • 当 n1 != x : 抵消的所有数字中,众数 x 的数量最少为 0 个,最多为一半。

利用此特性,每轮假设发生 票数和 =0 都可以 缩小剩余数组区间 。当遍历完成时,最后一轮假设的数字即为众数。

算法流程:

1.初始化: 票数统计 votes = 0 , 众数 x。

2.循环: 遍历数组 nums 中的每个数字 num 。

  • 当 票数 votes 等于 0 ,则假设当前数字 num 是众数。

  • 当 num = x 时,票数 votes 自增 1 ;当 num != x 时,票数 votes 自减 1 。

3.返回值: 返回 x 即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值