题解:找出整型数组中占比超过一半的数(摩尔投票法)

55 阅读3分钟

题解:找出整型数组中占比超过一半的数

找出整型数组中占比超过一半的数 - MarsCode

问题描述

小R从班级中抽取了一些同学,每位同学都会给出一个数字。已知在这些数字中,某个数字的出现次数超过了数字总数的一半。现在需要你帮助小R找到这个数字。

思路分析

解法一:哈希表

最暴力的解法当然是统计每个数的出现频数,最后返回频数大于数组长度一半的数即可

关键步骤解释

  1. 初始化哈希表:我们使用一个空的字典 count_dict 来存储每个数字及其出现的次数。
  2. 统计频率:遍历数组 array,对于每个数字 num,我们检查它是否已经在 count_dict 中。如果存在,我们增加其计数;如果不存在,我们将其添加到字典中并设置计数为1。
  3. 查找多数元素:计算数组长度的一半 half_length,然后遍历 count_dict,找到出现次数超过 half_length 的数字并返回。

这个方法的时间复杂度是 O(n),空间复杂度也是 O(n),其中 n 是数组的长度。

def solution(array):
    # 初始化一个空的哈希表
    count_dict = {}
    # 遍历数组,统计每个数字的出现次数
    for num in array:
        # 如果数字已经在哈希表中,增加其计数
        if num in count_dict:
            count_dict[num] += 1
        # 如果数字不在哈希表中,将其添加到哈希表并设置计数为1
        else:
            count_dict[num] = 1
    # 计算数组长度的一半
    half_length = len(array) // 2
    # 遍历哈希表,找到出现次数超过一半的数字
    for num, count in count_dict.items():
        if count > half_length:
            return num

if __name__ == "__main__":
    print(solution([1, 3, 8, 2, 3, 1, 3, 3, 3]) == 3)
解法二:摩尔投票法

思路

  1. 初始化计数器:使用一个计数器 vote 和一个变量 res 来记录当前的候选多数元素。
  2. 遍历数组:对于数组中的每个元素,如果计数器 vote 为0,则将当前元素设为候选多数元素,并将计数器加1。如果当前元素与候选多数元素相同,则增加计数器;否则,减少计数器。
  3. 返回结果:最终,res 中存储的就是多数元素。

数据结构选择

  • 计数器 vote:用于记录当前候选多数元素的“票数”。
  • 变量 res:用于存储当前的候选多数元素。

算法步骤

  1. 初始化 vote 为0,res 为0。

  2. 遍历数组中的每个元素 num

    • 如果 vote 为0,将 res 设为 num
    • 如果 res 等于 num,增加 vote
    • 否则,减少 vote
  3. 返回 res

def solution(array):
    vote = 0  # 初始化计数器
    res = 0   # 初始化候选多数元素
    for num in array:
        if vote == 0:  # 如果计数器为0,更新候选多数元素
            res = num
        if res == num:  # 如果当前元素与候选多数元素相同,增加计数器
            vote += 1
        else:  # 否则,减少计数器
            vote -= 1
    return res  # 返回候选多数元素

if __name__ == "__main__":
    print(solution([1, 3, 8, 2, 3, 1, 3, 3, 3]) == 3)