LeetCode 169. Majority Element 解题报告

本文介绍了解决LeetCode 169题 Majority Element 的多种方法,包括直观的计数方法、线性时间投票算法及排序法。讨论了每种方法的原理与实现,特别强调了线性时间投票算法的独特之处。

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

LeetCode 169. Majority Element 解题报告

题目描述

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exist in the array.


示例

没有给出,自己想想就知道题意是什么。


限制条件

没有明确给出。


解题思路

我的思路:

很直观的思路:
- 用一个map保存数组中出现的数字跟出现次数。
- 遍历数组并更新数字及其出现次数,如果某个数字的次数大于数组长度一半就记下该数字,并结束遍历。
- 返回记录的数字
就这样轻松地地通过了,不过惯例看看dicuss,好吧,又一次被大牛们震撼了,简单的题也存在着巧妙的解法。下面讲解大牛们的A Linear Time Majority Vote Algorithm

其他思路1

A Linear Time Majority Vote Algorithm用于找出数组中出现次数最多的元素。这个算法存在很大的限制,就是数组中必须存在出现次数最多的元素,并且次数是大于n/2。刚好这道题说了满足这两个限制,所以可以使用该算法。
算法的核心步骤是遍历一遍数组nums并且维护一组信息(当前元素e,元素次数count)。
- 初始时,当前元素e为第一个元素nums[0],元素次数count=1。
- 从nums[1]开始,如果e与nums[i]不同,元素次数count自减1,如果e与nums[i]相同,元素次数count自增1。
- 当count=0,更新e为目前检测的数组元素nums[i],并且count自增1。
- 最后,e保存的就是出现次数最多的元素。
这种算法使用了最多元素的次数是大于n/2这一条件,其他元素的个数和肯定比n/2小,所以不管它们的个数有多大,遇到了n/2个最大元素e,count都会减为0,从而使得e保存的是出现最多的元素e。

其他思路2

还有一种思路是排序后返回中间的元素,而这种算法同样是利用了最多元素的次数是大于n/2这一条件。在排序时,由于最多的元素e的个数比n/2大,所以肯定会出现在排序后数组的中间位置。
然而有人举出了如下两个例子说明这个算法是错误的
[1,1,2,3]
[1,2,3,3]
但是本身这两个例子存在问题,题目说的是最大次数比 ⌊ n/2 ⌋要大(appears more than ⌊ n/2 ⌋ times),如果是这两个例子,那么最大次数至少要等于3,而这两个例子中最大次数是2=⌊ n/2 ⌋,所以不是正确的测试用例,因此这种算法的思想是正确的。


代码

我的代码

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        map<int, int> numberTimes;
        int threshold = nums.size() / 2;
        int major = 0;

        for (auto n: nums) {
            numberTimes[n]++;
            if (numberTimes[n] > threshold) {
                major = n;
                break;
            }
        }

        return major;
    }
};

参考代码1

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int major = nums[0], count = 1; 

        for (int i = 1; i < nums.size(); i++) {
            if (count == 0) {
                count++; 
                major = nums[i];
            } else if (major == nums[i])
                count++;
            else 
                count--;
        } 

        return major;
    }
};

参考代码2

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int len = nums.size();

        sort(nums.begin(), nums.end());

        return nums[len / 2];
    }
};

总结

这道题抓住了最多次数大于n/2的条件能够有不同的解法,而使用普通的记数方法也可以通过。做完这道题,比较大的收获时开阔了解题的思路,同样解题时要多注意关键的条件,说不定能利用关键条件快速解决问题。
完成第三个坑,继续下一个坑,加油加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值