LeetCode169. Majority Element题解

这一周的课程讲的是分治法,于是选一个分治法里面最简单来做,发现并没有使用到分治法的思想,尴尬→_→

1. 题目描述

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.

2. 分析

题目描述简单的一清二楚,给个数组,然后输出其中的一个元素,这个元素在数组里面出现的次数大于⌊ n/2 ⌋次。

2.1. 解法1:利用map

拿到题目,最容易想到的解法就是利用Map:把原来的数组里面的元素映射到map里面,然后去计数每个元素出现的次数。map的第一个键值作为元素,第二个值作为在原数组中出现的个数。
具体做法是:我们开启一层循环,判断每一个原数组中出现的元素是否可以直接插入map,如果map中没出现,就把它作为键,将1次作为值,生成一个键值对插入进map。如果出现过该键,则该键对应的值加一,之后判断该值是否超过了⌊ n/2 ⌋,达到的话,直接返回该键,表明该键元素就是在原数组中出现次数超过了⌊ n/2 ⌋。

2.2. 解法2:观察

有点作弊的嫌疑哦,我们仔细思考一下,一个数组,如果里面有一个数字它出现的次数超过了⌊ n/2 ⌋,那么我们将数组排序就可以知道,⌊ n/2 ⌋的位置肯定就是这个元素了。原因很简单:无论该元素是数组中最大或者最小的元素,它在数组里面出现的次数都会保证⌊ n/2 ⌋的位置肯定是它。

2.3. 解法3:Moore Voting

看了讨论区大佬们的算法,觉得智商被碾压了。有一种很巧妙的算法:将Majority设为数组中第一个元素,设一个计数器从1开始接下来遍历:如果计数器为0则将当前数组元素设为Majority,否则,如果当前Majority与下一个元素相等,计数器加1,否则计数器减1。它的思想其实就是当Majority等于0的时候,目前数组中还没有重复次数能够超过一半的元素。

3. 源码

3.1. map方法代码
class Solution {
public:
    int majorityElement(vector<int>& nums) {
        map<int, int> hash;
        int i;
        for (i = 0; i < (int)nums.size(); i++) {
            if (!hash.empty()) {
                map<int, int>::iterator it = hash.find(nums[i]);
                if (it == hash.end()) {
                    hash.insert(pair<int, int>(nums[i], 1));
                }
                else {
                    //根据键找到值,对值加一操作,表明出现的次数加一
                    int temp = (*it).second + 1;
                    hash.erase(nums[i]);
                    hash.insert(pair<int, int>(nums[i], temp));
                    if (temp > (int)(nums.size() / 2)) {
                        return nums[i];
                    }
                }
            }
            else {
                hash.insert(pair<int, int>(nums[i], 1));
            }
        }
        return nums[0];
    }
};
3.2. 观察方法,两行搞定
class Solution {
public:
    int majorityElement(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        return nums[nums.size()/2];
    }
};
3.3. Moore Voting
class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int counter = 1;
        int i;
        int majority = nums[0];
        for (i = 1 ; i < (int)nums.size(); i++) {
            if (counter == 0) {
                counter++;
                majority = nums[i];
            }
            else if (majority == nums[i]) {
                counter ++;
            }
            else {
                counter --;
            }
        }
        return majority;
    }
};

4. 心得

本来是练练分治法,没想到没用到分治法。不过后来看了大佬们的讨论,自己觉得其实Moore Voting也是利用了分治法的思想:在遍历中不断判断已检测的部分是否符合有元素出现次数超过一半,没有的话对数组剩下的部分执行相同操作,这勉强算作分治法的一个应用吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值