zoukankan      html  css  js  c++  java
  • LeetCode #229. Majority Element II 数组 摩尔投票法

    Description


    Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times.

    Note: The algorithm should run in linear time and in O(1) space.

    Example 1:

    Input: [3,2,3]
    Output: [3]
    

    Example 2:

    Input: [1,1,1,3,3,2,2,2]
    Output: [1,2]
    



    思路


    解法一

    借鉴了#169 中的摩尔投票法,但是使用该算法的前提是数组必须存在一个 majorityElement 且它的出现频数大于数组元素数目的一半。因此,需要对该算法进行修改。

    由题推得,任意一个数组出现次数大于 n/3 的数最多有两个,网上提供了证明:如果有超过两个,也就是至少三个数字满足“出现的次数大于 n/3”,那么就意味着数组里总共有超过 3*(n/3) = n 个数字,这与已知的数组大小矛盾,所以,只可能有两个或者更少。

    原来的算法只是利用一个计数器,现在新增一个计数器,用两个计数器来统计出现次数大于 n/3 的数。

    如果当前数字是这两个数中的一个,则对应计数器 + 1;
    如果当时数字不是这两个数中的一个,则两个计数器都减一;
    如果有一个计数器的值为 0 ,则该计数器重置为 1,用来统计当前数字的出现次数。

    这三个判断必须以 if-else 方式执行,否则将不符合 Moore Voting 的思想。

    由于之前 #169 中限定了一定会有大多数存在,故而当时省略了验证候选众数的步骤。但是这道题却没有这种限定,即满足要求的Majority Element可能不存在,所以要有验证步骤。

    时间复杂度:O(n)
    空间复杂度:O(1)

    耗时 12 ms, Memory 8.5 MB, ranking 89.57%

    class Solution {
    public:
        vector<int> majorityElement(const vector<int> &nums) {
            if (nums.empty()) return {};
            
            int mj1 = 0, mj2 = 0, cnt1 = 0, cnt2 = 0;
            for (int element : nums) {
                if (element == mj1) {
                    ++cnt1;
                } else if (element == mj2) {
                    ++cnt2;
                } else if (!cnt1) {
                    mj1 = element;
                    cnt1 = 1;
                } else if (!cnt2) {
                    mj2 = element;
                    cnt2 = 1;
                } else {
                    --cnt1;
                    --cnt2;
                }
            }
            
            // recheck whether both mj1 and mj2 are majority element
            cnt1 = 0, cnt2 = 0;
            for (int element : nums) {
                if (element == mj1) {
                    ++cnt1;
                    continue;  // mj1 != mj2, so don't need to judge next condition
                }
                
                if (element == mj2) {
                    ++cnt2;
                    continue;
                }
            }
            
            int len = nums.size()/3;  // 2 = 8 / 3
            if (cnt1 > len && cnt2 > len) {
                return {mj1, mj2};
            } else if (cnt1 > len) {
                return {mj1};
            } else if (cnt2 > len) {
                return {mj2};
            } else {
                return {};
            }
        }
    };
    



    参考




  • 相关阅读:
    spring4之依赖注入的三种方式
    Hibernate之总结
    Hibernate之dynamic-update
    ThinkPhp调用webservice
    Robot Framework:Web自动化之-元素处理
    Robot Framework:Web自动化之-元素定位
    RobotFramework:python+robotframework+selenium2library测试环境部署说明文档
    Robot Framework:Httplibrary库
    URL备忘
    Windows:CMD命令备忘
  • 原文地址:https://www.cnblogs.com/Bw98blogs/p/12712057.html
Copyright © 2011-2022 走看看