找出整型数组中占比超过一半的数 | 豆包MarsCode AI刷题

49 阅读2分钟

目标

  • 找出出现次数超过一半的数字。

关键点

  • 数组中存在一个数字,其出现次数严格大于数组长度的一半。
  • 因此,即使数组中有其他不同的数字,这个特定的数字也会在数组中占据主导地位。
  • 可以利用这一点来设计高效的算法。

摩尔投票算法 (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

代码步骤详解

  1. 初始化

    • candidate 初始化为 None,表示还没有确定候选者。
    • count 初始化为 0,表示计数器初始为 0。
  2. 遍历数组

    • 使用 for num in array 遍历数组中的每个元素 num

    • 条件判断

      • 如果 count 为 0,说明之前的元素已经相互抵消,选择当前元素 num 作为新的候选者,并将 count 设置为 1。
      • 如果当前元素 num 与候选者 candidate 相同,增加 count
      • 如果当前元素 num 与候选者 candidate 不同,减少 count
  3. 返回结果

    • 遍历完成后,candidate 即为所求的多数元素,返回 candidate