在给定的整形数组中,要求找出占比超过一半的数,我们可以通过 "摩尔投票法"(Boyer-Moore Voting Algorithm)来实现。这个算法的时间复杂度为O(n),空间复杂度为O(1),是一个高效且常用的方法。
- 问题分析 给定一个整形数组,我们需要找到一个元素,其出现次数超过数组总长度的一半,即出现次数大于 n/2,其中n是数组的长度。这样的元素在数组中最多只会有一个,因为如果有两个以上的元素出现次数超过一半,它们的总和就会超过整个数组的长度,这显然是不可能的。
- 摩尔投票法的原理 摩尔投票法的核心思想是通过一次遍历就找出可能的候选元素,并通过第二次遍历验证该候选元素是否确实占据了超过一半的比例。具体步骤如下: 步骤一:找出候选元素
1.初始化一个候选元素 candidate 和一个计数器 count,count 初始为 0。 2.遍历数组:
3.如果 count 为 0,说明当前没有确定的候选元素,这时将当前元素设为候选元素 candidate,并将 count 设为 1。 4.如果当前元素等于 candidate,则 count 加 1。 5.如果当前元素不等于 candidate,则 count 减 1。
通过这个过程,我们最终能确定一个候选元素,该元素有可能是占比超过一半的元素。 步骤二:验证候选元素 由于摩尔投票法仅确定了一个候选元素,并不能直接保证它的出现次数确实超过了数组的一半。因此,在第二次遍历中,我们需要确认候选元素的出现次数是否大于 n/2。 3. 代码实现 def majorityElement(nums): # 步骤一:找出候选元素 candidate = None count = 0 for num in nums: if count == 0: candidate = num count += (1 if num == candidate else -1)
# 步骤二:验证候选元素
count = 0
for num in nums:
if num == candidate:
count += 1
if count > len(nums) // 2:
return candidate
else:
return None # 如果没有超过一半的元素,返回None
4. 解释代码
6.步骤一:在第一次遍历数组时,我们通过计数来找出可能的候选元素。每次遇到相同的元素就增加计数,遇到不同的元素就减少计数。当计数为零时,更新候选元素。 7.步骤二:第二次遍历数组,统计候选元素的出现次数。如果该次数大于 n/2,则返回该元素,反之返回 None。
- 例子 假设我们有一个数组:[3, 2, 3]
8.在第一次遍历中: 9.candidate = 3, count = 1 10.candidate = 3, count = 2 11.candidate = 3, count = 1 (因为遇到 2) 12.结束后,候选元素为 3。 13.第二次遍历: 14.统计 3 出现了 2 次,数组长度为 3,所以 3 的出现次数确实超过了 3 / 2 = 1.5,因此返回 3。
- 复杂度分析
15.时间复杂度:O(n),我们只遍历了数组两次,因此时间复杂度是线性的。 16.空间复杂度:O(1),除了几个辅助变量外,我们没有使用额外的空间。
- 总结 摩尔投票法是一个高效的解决方案,适用于找出一个数组中占比超过一半的元素(如果存在的话)。它通过两次遍历、一次选举和一次验证,成功地找出了结果,且时间复杂度为 O(n),空间复杂度为 O(1),非常适合处理大规模数据。