LeetCode:169. Majority Element && 229. Majority Element II

在这里插入图片描述
在这里插入图片描述

找出数组中出现次数最多的数字。
记录这题是因为这题有特定的算法,叫做Boyer-Moore Majority Vote algorithm。另外,在第二题实现该算法时有一些细节需要注意。

  1. Majority Element
class Solution {
public:
    int majorityElement(vector<int>& nums) {
        if (nums.empty())
            return -1;
        int candidate, count = 0;
        for (const int& item : nums) {
            if (item == candidate)
                ++count;
            else if (count == 0){
                candidate = item;
                count = 1;
            }
            else --count;       
        }
        return candidate;
    }
};

直观上感受这个算法就是相互抵消,最后留下谁就是谁最多。

  1. Majority Element II
    首先直接看代码:
class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {
        if (nums.empty())
            return vector<int>();
        vector<int> ret;
        int candidate1, candidate2, count1 = 0, count2 = 0;
        for (const auto &item : nums) {
            if (item == candidate1)
                count1++;
            else if (item == candidate2)
                count2++;
            else if (count1 == 0) {
                candidate1 = item;
                count1 = 1;
            }
            else if (count2 == 0) {
                candidate2 = item;
                count2 = 1;
            }
            else {
                count1--;
                count2--;
            }
        }
        if (count(nums.begin(), nums.end(), candidate1) > nums.size()/3)
            ret.push_back(candidate1);
        if (count(nums.begin(), nums.end(), candidate2) > nums.size()/3)
            ret.push_back(candidate2);
        return ret;
    }
};

这个实现中有些细节需要注意。
1.最后还需要确保一下这个数字出现的次数,否则会出错。
2.如果不仔细看这段代码的话,会有这样的疑问:如果有个数字出现的次数刚超过1/3,少于1/2,其余数字都不相同,那么这个数字不是会被抵消完吗?比如:1,1,1,2,3,4,5,6.最后1的count不是会被抵消完吗?其实不然,需要注意的是,在代码的实现中,我们在count减1之后没有测试该count是否为0,而是留到下一轮才测试,这样的一个后果是对于1的count,我们有两个不是1的数字出现,才会对该count减1.比如,迭代完1,1,1,2之后,[candidate1,count1,candidate2,count2]的值为[1,3,2,1],迭代完3之后为[1,2,2,0],迭代完4之后为[1,2,4,1],所以,迭代了两个不是1的数,count1才减少了1.
也就是说,对于不是待选的那些数,出现两次才会抵消掉待选的那些数一次,所以对于这次选出出现次数大于1/3的,是有效的。

posted @ 2018-12-14 20:20  于老师的父亲王老爷子  阅读(15)  评论(0)    收藏  举报