题解:找出整型数组中占比超过一半的数
问题描述
小R从班级中抽取了一些同学,每位同学都会给出一个数字。已知在这些数字中,某个数字的出现次数超过了数字总数的一半。现在需要你帮助小R找到这个数字。
思路分析
解法一:哈希表
最暴力的解法当然是统计每个数的出现频数,最后返回频数大于数组长度一半的数即可
关键步骤解释
- 初始化哈希表:我们使用一个空的字典
count_dict来存储每个数字及其出现的次数。 - 统计频率:遍历数组
array,对于每个数字num,我们检查它是否已经在count_dict中。如果存在,我们增加其计数;如果不存在,我们将其添加到字典中并设置计数为1。 - 查找多数元素:计算数组长度的一半
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)
解法二:摩尔投票法
思路
- 初始化计数器:使用一个计数器
vote和一个变量res来记录当前的候选多数元素。 - 遍历数组:对于数组中的每个元素,如果计数器
vote为0,则将当前元素设为候选多数元素,并将计数器加1。如果当前元素与候选多数元素相同,则增加计数器;否则,减少计数器。 - 返回结果:最终,
res中存储的就是多数元素。
数据结构选择
- 计数器
vote:用于记录当前候选多数元素的“票数”。 - 变量
res:用于存储当前的候选多数元素。
算法步骤
-
初始化
vote为0,res为0。 -
遍历数组中的每个元素
num:- 如果
vote为0,将res设为num。 - 如果
res等于num,增加vote。 - 否则,减少
vote。
- 如果
-
返回
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)