leetcode刷题--多数元素

本文介绍了如何使用摩尔投票算法在O(n)时间和O(1)空间复杂度内解决LeetCode中的多数元素问题。通过遍历数组,动态更新候选多数元素并计数,最终找到出现次数超过n/2的元素。文章提供了算法的正确性证明、Java实现及复杂度分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:nums = [3,2,3]
输出:3
示例 2:
输入:nums = [2,2,1,1,1,2,2]
输出:2
提示:
n == nums.length
1 <= n <= 5 * 104
-109 <= nums[i] <= 109
进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。
为了解决这个问题,我们可以使用一种称为“摩尔投票算法”(Boyer-Moore Voting Algorithm)的高效算法。这个算法在时间复杂度为O(n)且空间复杂度为O(1)的条件下解决了这个问题。

摩尔投票算法的基本思想

  1. 维护一个候选多数元素candidate和一个计数器count。初始时,candidate可以为任意值,count为0。
  2. 遍历数组nums中的每个元素x
    • 如果count为0,我们将candidate设置为x,即认为当前元素可能是多数元素。
    • 如果x等于candidate,则将count加1。
    • 如果x不等于candidate,则将count减1。
  3. 遍历完成后,candidate即为整个数组的多数元素。

算法的正确性

由于多数元素在数组中出现的次数大于n/2,那么在遍历过程中,candidate最终一定会被设置为多数元素。因为每当count减到0时,意味着到目前为止,没有任何元素可以成为多数元素。此时,可以将candidate设置为当前元素,并开始重新计数。由于多数元素的数量超过了数组长度的一半,所以candidate最终一定会是多数元素。

Java实现

public class Solution {
    public int majorityElement(int[] nums) {
        int count = 0;
        Integer candidate = null;

        for (int num : nums) {
            if (count == 0) {
                candidate = num;
            }
            count += (num == candidate) ? 1 : -1;
        }

        return candidate;
    }
}

复杂度分析

  • 时间复杂度:O(n),其中n是数组nums的长度。我们只需要遍历数组nums一次。
  • 空间复杂度:O(1),我们只需要常数空间存放candidatecount

为什么这个算法有效?

每当count变为0时,就更换candidate。这意味着到目前为止,之前的所有元素中,没有任何元素的出现次数能够超过数组长度的一半。因此,可以放弃这些元素,从当前元素重新开始计数。
由于多数元素的出现次数大于n/2,即使它在数组的前半部分被抵消,剩余的部分中它仍然是出现次数最多的元素。因此,最后candidate变量中存储的元素,就是整个数组的多数元素。
这个算法的巧妙之处在于,它利用了多数元素出现次数超过总数一半的特性,通过一次遍历就能找到这个元素,而且只用了O(1)的额外空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值