📅  最后修改于: 2023-12-03 15:07:35.172000             🧑  作者: Mango
这是国际空间研究组织(ISRO) 2020年计算机科学(CS)招聘考试中的第22个问题。
给定一个整数数组,编写一个程序,以线性时间复杂度和常量空间复杂度找到该数组的大多数元素。
大多数元素是指在该数组中出现次数大于 ⌊ n/2 ⌋ 的元素。说明:你可以假设该数组是非空的,并且给定的数组总是存在多数元素。
输入: [3,2,3] 输出: 3
输入: [2,2,1,1,1,2,2] 输出: 2
在数组中查找出现次数最多的元素并不是一件非常困难的事情,可以使用一个哈希表将数组中所有元素出现的次数统计出来,最后选取最大值即可。但是这个方法的时间复杂度较高。
在这个问题中,我们不能使用上述的哈希表方法,因为题目要求我们 线性时间复杂度 和 使用 常量空间复杂度。那么怎么办呢?
使用Boyer-Moore投票算法。
Boyer-Moore投票算法本质上是找出数组中出现次数最多的元素。假设数组中有一个元素出现次数较多,那么将对调它与其他元素的比例,如果仍有相同数量的该元素,那么该元素一定是成为多数元素。
因为数组里的大多数元素出现次数必定大于⌊ n/2 ⌋,所以设立两个变量 candidate
和 count
,初始值为数组中的第一个元素。遍历数组时,当下一个元素与之前的元素相等则 count
加 1,否则 count
减 1。当 count
减为 0 时,说明前面的元素为众数的可能性已经被抵消为0了,因此将下一个元素设为 candidate
并将 count
赋值为 1。
最后,判断 candidate
是否真正是众数。
class Solution:
def majorityElement(self, nums: List[int]) -> int:
candidate = nums[0]
count = 1
for i in range(1, len(nums)):
if candidate == nums[i]:
count += 1
else:
count -= 1
if count == 0:
candidate = nums[i]
count = 1
return candidate
Boyer-Moore投票算法是一种 求解数值型或字母型的众数 的高效方法。由于该算法只需要一次遍历数组,时间复杂度为 O(n) ,同时由于只使用两个变量 candidate 和 count ,空间复杂度为 O(1) 。这个算法在很多情况下都非常有用,比如说在选举、病人识别或者信号处理等方面。