伴学笔记7| 豆包MarsCode AI刷题

84 阅读2分钟

学习笔记:找出整型数组中占比超过一半的数

问题描述

给定一个整型数组,数组中某个数字的出现次数超过了数组长度的一半,要求找出这个数字。

关键点

- 题目本质:寻找数组中占比超过一半的元素,即出现次数大于 ⌊n/2⌋ 次的元素。
- 由于该元素出现次数超过了数组总长度的一半,因此在数组中它的数量一定是最多的。

解法思路

根据这个特点,我们可以使用一种非常高效的算法:摩尔投票法 (Boyer-Moore Voting Algorithm)。

摩尔投票法

摩尔投票法的核心思想是:通过一轮遍历,使用计数器消除不同的元素,最终剩下的那个元素就是占比超过一半的数。

算法步骤
1. 初始化两个变量:
candidate:记录当前的候选元素;
count:记录候选元素的计数。
2. 遍历数组中的每个元素:
- 如果 count 为 0,则将当前元素设置为 candidate,并将 count 设为 1。
- 如果当前元素等于 candidate,则 count 加 1。
- 如果当前元素不等于 candidate,则 count 减 1。
3. 最终 candidate 就是占比超过一半的元素。

算法证明

该算法可以保证在多次不同元素的抵消过程中,超过一半的那个元素不会被完全抵消掉。因此,遍历结束时的 candidate 就是我们要找的占比超过一半的元素。

代码实现

def majority_element(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  

测试样例

# 样例1  
array1 = [138231333]  
print(majority_element(array1))  # 输出:3  
  
# 样例2  
array2 = [5551255]  
print(majority_element(array2))  # 输出:5  
  
# 样例3  
array3 = [99998988]  
print(majority_element(array3))  # 输出:9  

心得体会

1. 摩尔投票法的优势:该算法的时间复杂度为 O(n),且只需常数级别的额外空间,即 O(1)。相比于其他方法(如哈希表统计频次),它的空间复杂度更低,非常高效。
2. 问题的特点:由于题目假设存在一个出现次数超过数组长度一半的元素,因此可以省略第二轮验证。在实际应用中,如果没有这个假设,则需要在第一阶段找出候选元素后,再进行一次遍历验证该元素的出现次数是否超过一半。
3. 扩展思考:摩尔投票法不仅可以用于解决该问题,还可以应用于类似的需要找出数组中频率最高元素的问题。