leetcode:169多数元素------摩尔投票法

博客介绍了如何使用摩尔投票法解决LeetCode第169题,即在数组中找出多数元素。这种方法能在O(n)的时间复杂度和O(1)的空间复杂度下找到绝对众数。文章提供了C语言的代码实现,并强调了摩尔投票法适用于寻找绝对众数而非众数的情况。

摘要生成于 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) 的算法解决此问题。

摩尔投票法:

摩尔投票是一种用来解决绝对众数问题的算法。

在一个集合中,如果一个元素的出现次数比其他所有元素的出现次数之和还多,那么就称它为这个集合的绝对众数。等价地说,绝对众数的出现次数大于总元素数的一半

摩尔投票算法的基本思想是维护一个候选众数和其出现的次数。遍历数组,当遇到与候选众数相同的数时,计数器加一,否则减一。当计数器归零时,更换候选众数。由于题目中明确给出多数元素一定存在,因此遍历完数组后,候选众数即为所求。

注意:

摩尔投票法解决的是绝对众数,不是众数。

例如:

C语言代码实现:

int majorityElement(int* nums, int numsSize) {
    int candidate = nums[0];
    int count = 1;

    for (int i = 1; i < numsSize; i++) {
        if (nums[i] == candidate) {
            count++;
        } else {
            count--;
        }

        if (count == 0) {
            candidate = nums[i];
            count = 1;
        }
    }

    return candidate;
}

如果计数为零,就选择新的候选人,因为前面的谁都不占优势了,后面出现谁就选谁。

具体参考大佬的文章:算法学习笔记(78): 摩尔投票 - 知乎 (zhihu.com)

如果要找N个数

int majorityElement(int* nums, int numsSize,const int N) {
    int m[N], cnt[N];
    memset(m, 0, sizeof(m));
    memset(cnt, 0, sizeof(cnt));

    for (int k = 0; k < numsSize; k++) {
        int e = nums[k];
        int i;
        for (i = 0; i < N; i++) {
            if (m[i] == e) {
                cnt[i]++;
                break;
            }
        }
        
        if (i == N) {
            int j;
            for (j = 0; j < N; j++) {
                if (cnt[j] == 0) {
                    m[j] = e;
                    cnt[j] = 1;
                    break;
                }
            }
            
            if (j == N) {
                for (int l = 0; l < N; l++) {
                    cnt[l]--;
                }
            }
        }
    }
    
    // 最后需要验证答案是否符合要求
    int majority = 0;
    int maxCount = 0;
    for (int i = 0; i < N; i++) {
        if (cnt[i] > maxCount) {
            maxCount = cnt[i];
            majority = m[i];
        }
    }
    
    return majority;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐果然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值