zoukankan      html  css  js  c++  java
  • [LeetCode 229] Majority Element II

    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]

     

    This is an extension of the Boyer-Moore Voting Majority Algorithm covered in the Majority Element problem. The difference is that there may be up to 2 different numbers whose frequencies are > n / 3. Instead of running 1 candidate and 1 counter, we run 2 candidates and 2 counters for each.  Assign two different numbers to candidate 1 and 2, the actual values here do not matter as long as they are not the same. Then go over the input array and do the following.

    1. if nums[i] == candidate1, cnt1++;

    2. else if nums[i] == candidate2, cnt2++;

    3. else if cnt1 == 0, set candidate1 to nums[i];

    4. else if cnt2 == 0, set candidate2 to nums[i];

    5. else cnt1--, cnt2--. 

    Why do we need to decrease both counters in case 5? Think of it this way: we are trying to find 3 different numbers to hide. In case 5, we have just found an all different triplet. We hide all 3 different numbers: nums[i] is ignored, candidate1 and candidate2' counters decrease by 1. 

    Why does this modification on the voting algorithm works? If there is at least 1 numbers with > n / 3 frequency, then in order to completely hide it, we need > n / 3 * 2 numbers of different value to achieve this. This exceeds the total number of elements n. 

    class Solution {
        public List<Integer> majorityElement(int[] nums) {
            List<Integer> ans = new ArrayList<>();
            int c1 = 0, c2 = 1, cnt1 = 0, cnt2 = 0;
            for(int i = 0; i < nums.length; i++) {
                if(nums[i] == c1) {
                    cnt1++;
                }
                else if(nums[i] == c2) {
                    cnt2++;
                }
                else if(cnt1 == 0) {
                    c1 = nums[i];
                    cnt1++;
                }
                else if(cnt2 == 0) {
                    c2 = nums[i];
                    cnt2++;
                }
                else {
                    cnt1--;
                    cnt2--;
                }
            }
            cnt1 = 0;
            cnt2 = 0;
            for(int i = 0; i < nums.length; i++) {
                if(nums[i] == c1) {
                    cnt1++;
                }
                else if(nums[i] == c2) {
                    cnt2++;
                }
            }
            if(cnt1 > nums.length / 3) {
                ans.add(c1);
            }
            if(cnt2 > nums.length / 3) {
                ans.add(c2);
            }
            return ans;
        }
    }

     

    Related Problems 

    Majority Element 

    Majority Element III

    Single Number 

    Single Number II

    Single Number III

  • 相关阅读:
    Extjs4.0以上版本 Ext.Ajax.request请求的返回问题
    C# NPOI 操作Excel 案例
    C# Microsoft.Office 操作Excel总结
    asp.net core NLog将日志写到文件
    新装的SSMS一打开就显示VS许可证过期,但VS又运行正常,解决方法。
    sql server 查询log日志 sql语句
    sql server 删除所有表及所有存储过程、所有视图和递归查询、数字类型转为字符串
    C#使用Selenium+PhantomJS抓取数据
    python爬虫实例项目大全
    SQL Server TVPs 批量插入数据
  • 原文地址:https://www.cnblogs.com/lz87/p/7221385.html
Copyright © 2011-2022 走看看