目标
- 找出出现次数超过一半的数字。
关键点
- 数组中存在一个数字,其出现次数严格大于数组长度的一半。
- 因此,即使数组中有其他不同的数字,这个特定的数字也会在数组中占据主导地位。
- 可以利用这一点来设计高效的算法。
摩尔投票算法 (Boyer-Moore Voting Algorithm)
基本思想
-
维护一个候选者
candidate和一个计数器count。 -
遍历数组:
- 如果
count为 0,选择当前元素作为新的候选者,并将count设置为 1。 - 如果当前元素与候选者相同,增加
count。 - 否则,减少
count。
- 如果
-
遍历完成后,
candidate即为所求的多数元素。
为什么有效?
- 当
count为 0 时,选择当前元素作为新的候选者,意味着之前的元素相互抵消了。 - 由于多数元素的出现次数超过了一半,最终
count不会为 0,而candidate会是多数元素。
def solution(array):
candidate = None
count = 0
for num in array:
if count == 0:
candidate = num
count = 1
elif num == candidate:
count += 1
else:
count -= 1
return candidate
if __name__ == "__main__":
# 测试用例
print(solution([1, 3, 8, 2, 3, 1, 3, 3, 3]) == 3) # True
print(solution([5, 5, 5, 1, 2, 5, 5]) == 5) # True
print(solution([9, 9, 9, 9, 8, 9, 8, 8]) == 9) # True
代码步骤详解
-
初始化:
candidate初始化为None,表示还没有确定候选者。count初始化为 0,表示计数器初始为 0。
-
遍历数组:
-
使用
for num in array遍历数组中的每个元素num。 -
条件判断:
- 如果
count为 0,说明之前的元素已经相互抵消,选择当前元素num作为新的候选者,并将count设置为 1。 - 如果当前元素
num与候选者candidate相同,增加count。 - 如果当前元素
num与候选者candidate不同,减少count。
- 如果
-
-
返回结果:
- 遍历完成后,
candidate即为所求的多数元素,返回candidate。
- 遍历完成后,