LeetCode 169. Majority Element 解题报告

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、付费专栏及课程。

余额充值