leetcode169 229

来源:互联网 发布:mac 比较好用的3d软件 编辑:程序博客网 时间:2024/05/01 11:09

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.

本题的经典解决办法就是使用Boyer-Moore Majority Vote algorithm进行解决。算法的核心思路是:在遍历数组的过程中通过每个数字的“投票”来决定当前出现次数最多的元素。首先,确定一个数result = nums[0]为出现次数最多的数,此时它出现的次数count = 1,;接下来遍历数组,如果nums[i] == result,那么count ++,否则的话count --;如果发现count = 0了, 那么说明之前的result已经不是出现超过一半的数了(因为它result出现的次数与其他数字出现的次数相等),此时将result置为nums[i],count重新置1.直到数组结束。由于题目已经说明给定的测试用例一定保证有超过n/2的数,所以不用再对结果进行检验。直接返回result即可。

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int result = nums[0];
        int count = 1;
        
        for (int i = 1; i < nums.size(); i++){
            if (count == 0){
                result = nums[i];
                count = 1;
            }
            else{
                if (result == nums[i])
                    count ++;
                else
                    count --;
            }
        }
        return result;
    }
};


熟悉了一行思路,我们可以接着看题目229,Majority element 2,

Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.

这道题与前一道题很相像,这是要找出数组中出现次数超过n/3次的数字,并且要返回所有数字。因此,这句话提示我们,满足条件的数组可能不止一个,那么最多几个呢?最多只能有2个,因为2个数字都超过n/3了,那么剩下的数字个数就一定小于n/3.

那么对上述算法进行一个变形:用两个数result1,result2来保存结果,count1,count2保存它们出现的次数,初始值为1。按照上述算法的思路,对nums[i]来说,如果nums[i] == result1,那么count1 ++;如果nums[i] == result2,那么count2 ++;否则的话,count1 --,count2--;(此处必须要两个计数器同时减一)。同样的,如果count1 = 0,那么result1 = nums[i],count1 = 1;如果count2 = 0,那么result2 = nums[i],count2 = 1。

这样一直计算到数组结束,由于本次没有保证一定会出现超过n/3次的数字,因此还需要进行检测。对result1和result2,统计它们在数组中出现的次数如果大于n/3才返回,否则不返回。

class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {
        vector<int> result;
        if (nums.size() ==0)
            return result;
            
        int result_1 = 0;
        int result_2 = 1;
        int count_1 = 0;
        int count_2 = 0;
        
        for (int i = 0; i < nums.size(); i++){
            if (result_1 == nums[i]){
                count_1 ++;
            }
            else if (result_2 == nums[i]){
                count_2 ++;
            }
            else if (result_1 == 0){
                result_1 = nums[i];
                count_1 = 1;
            }
            else if (result_2 == 0){
                result_2 = nums[i];
                count_2 = 1;
            }
            else{
                count_1 --;
                count_2 --;
            }
        }
        
        count_1 = count_2 = 0;
        for (int i = 0; i < nums.size(); i++){
            if (nums[i] == result_1)
                count_1 ++;
            else if (nums[i] == result_2)
                count_2++;
        }
        
        if (count_1 > nums.size() / 3)
            result.push_back(result_1);
        if (count_2 > nums.size() / 3)
            result.push_back(result_2);
        
        return result;
    }
};