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

  • 相关阅读:
    CDB中plug PDB
    Oracle Flashback Technologies
    Oracle Flashback Technologies
    Oracle Flashback Technologies
    Oracle Flashback Technologies
    Oracle Flashback Technologies (总)
    Unplugging一个PDB
    使用已有PDB克隆PDB
    Oracle 12C -- 使用seed PDB创建新的pdb
    ROW_NUMBER() OVER函数的基本用法
  • 原文地址:https://www.cnblogs.com/lz87/p/7221385.html
Copyright © 2011-2022 走看看