• [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

  • 相关阅读:
    python 处理protobuf协议
    python 删除git Jenkinsfile文件
    如何用python操作XML文件
    Linux笔记
    JAVA bean为何要实现序列化
    mysql中给查询结果添加序号列
    生产问题之泛型自动推断(JDK1.7新特性)
    生产问题之StackOverflowError异常小记
    Linux下DB2指令总结
    简单理解TCP/IP协议
  • 原文地址:https://www.cnblogs.com/lz87/p/7221385.html
Copyright © 2020-2023  润新知