169. 求众数 && 229. 求众数 II

版权声明:如需转载请联系[email protected] https://blog.csdn.net/qq_20633793/article/details/82317998

不限定时间复杂度的话,很多人会先排序,再遍历的方法来做。不限定空间复杂度的话,很多人会用hash表来做。那么,有了这两个限定,就只能用摩尔投票算法了。

主元素问题典型解法。摩尔投票算法:时间复杂度O(n),空间复杂度O(1)

169

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

229

问题升级为选取大于等于n/3的数,简单分析可知,大于n/3的数最多有两个。(反证法轻轻松松即可证明),采取和169一样的摩尔投票算法,只不过,这次保留两个元素出现的次数。另外一个区别是这个题目没有保证此众数一定存在,所以,在得到两个候选众数之后,需要再次遍历一遍验证。

class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {
        vector<int> res;
        int m = 0, n = 0, cm = 0, cn = 0;
        for (auto &a : nums) {
            if (a == m) ++cm;
            else if (a ==n) ++cn;
            else if (cm == 0) m = a, cm = 1;
            else if (cn == 0) n = a, cn = 1;
            else --cm, --cn;
        }
        cm = cn = 0;
        for (auto &a : nums) {
            if (a == m) ++cm;
            else if (a == n) ++cn;
        }
        if (cm > nums.size() / 3) res.push_back(m);
        if (cn > nums.size() / 3) res.push_back(n);
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_20633793/article/details/82317998
今日推荐