📜  门| GATE-CS-2016(套装2)|第 62 题(1)

📅  最后修改于: 2023-12-03 15:42:18.676000             🧑  作者: Mango

题目描述

给定一个长度为 n 的整数数组 nums,其中有一个元素出现次数超过了 n/2,找出这个元素并返回。

函数签名
def majorityElement(nums: List[int]) -> int:
    pass
输入输出样例

示例一:

输入:

nums = [2,2,1,1,1,2,2]

输出:

2

示例二:

输入:

nums = [3,3,4]

输出:

3
思路分析

题目要求我们找出出现次数超过 n/2 的元素,而且我们知道这个元素一定存在。因此,我们可以考虑使用摩尔投票算法(Boyer–Moore majority vote algorithm)来解决这个问题。

摩尔投票算法的基本思想是设置一个变量 maj 用来记录当前遍历到的元素 x 出现的次数与其它所有元素出现次数之和的差,同时设置一个计数器 count 用来记录剩余元素中超过一半的元素的个数。根据题目的设定,由于至少有一个元素出现的次数超过了 n/2,因此在当前遍历到的元素 x 之前,maj 一定是正数,为已遍历的元素中目前出现次数超过了其它所有元素出现次数之和的元素个数。同时,由于要求的元素一定存在,count 的值始终为正。

在遍历整个数组时,我们首先将 maj 和 count 的值初始化为 0,并记录第一个元素 nums[0] 的值为 maj,接下来从第二个元素 nums[i] 开始遍历整个数组。每遍历到一个新元素 nums[i],我们首先将 count 的值加一,然后判断当前遍历到的元素是否等于 maj。如果相等,则 maj 的值加一;如果不相等,则 maj 的值减一。每次更新 maj 值后,我们都要判断 maj 是否等于当前遍历的元素 nums[i],如果相等,则继续将 maj 值增加或减少,否则继续遍历下一个元素。遍历结束后,maj 就是超过一半的元素,即所求的结果。

代码实现
from typing import List

def majorityElement(nums: List[int]) -> int:
    maj, count = nums[0], 0
    for num in nums:
        if count == 0:
            maj = num
        if maj == num:
            count += 1
        else:
            count -= 1
    return maj
复杂度分析

时间复杂度:O(n),其中 n 是数组的长度。我们最多遍历数组一次,每次遍历需要的时间复杂度是 O(1),因此总的时间复杂度是 O(n)。

空间复杂度:O(1)。我们只需要常数空间来存储变量 maj 和 count,因此空间复杂度是 O(1)。

参考资料
  1. Boyer–Moore majority vote algorithm