Baozi Leetcode solution 229: Major Element II
Problem Statement
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]
Problem link
Video Tutorial
You can find the detailed video tutorial here
Thought Process
It's a follow up question on Majority Element, given the hint, there should only be at most 2 elements that can satisfy the requirement (You cannot have 3 elements that all appear more than n/3 times). We can perform the voting algorithm on two potential candidates and later do an actual sum to eliminate the false positive (e.g., [1, 2, 1] would have both 1 and 2 as potential candidate, but 2 should not be included)
You can refer to Majority Element for a detailed explanation on the voting algorithm.
An extension could be changing n/3 to n/k. We just need extra arrays to store votes and candidates. It will take O(Nk) time complexity
Solutions
1 public List<Integer> majorityElement(int[] nums) { 2 List<Integer> res = new ArrayList<>(); 3 4 if (nums == null || nums.length == 0) { 5 return res; 6 } 7 8 int candidate1 = 1; 9 int candidate2 = 1; 10 int vote1 = 0; 11 int vote2 = 0; 12 13 for (int i = 0; i < nums.length; i++) { 14 if (nums[i] == candidate1) { 15 vote1++; 16 } else if (nums[i] == candidate2) { 17 vote2++; 18 } else if (vote1 == 0) { // the order of this if/else actually matters, you cannot put the 0 check first since [8, 8, 7, 7, 7] 19 candidate1 = nums[i]; 20 vote1++; 21 } else if (vote2 == 0) { 22 candidate2 = nums[i]; 23 vote2++; 24 } else { 25 vote1--; 26 vote2--; 27 } 28 } 29 30 /* This is what you should do if we want to put vote1 == 0 check at the beginning 31 for (int i = 0; i < nums.length; i++) { 32 if (vote1 == 0 && candidate2 != nums[i]) { 33 candidate1 = nums[i]; 34 } else if (vote2 == 0 && candidate1 != nums[i]) { 35 candidate2 = nums[i]; 36 } 37 if (nums[i] == candidate1) { 38 vote1++; 39 } else if (nums[i] == candidate2) { 40 vote2++; 41 } else { 42 vote1--; 43 vote2--; 44 } 45 } 46 */ 47 48 int count1 = 0; 49 int count2 = 0; 50 51 // need another pass to filter between the 2 candidates, e.g., [3, 2, 3], 2 is candidate but not more than 1/3 52 for (int num : nums) { 53 if (num == candidate1) { 54 count1++; 55 } else if (num == candidate2) { 56 count2++; 57 } 58 } 59 60 if (count1 > nums.length / 3) { 61 res.add(candidate1); 62 } 63 if (count2 > nums.length / 3) { 64 res.add(candidate2); 65 } 66 67 return res; 68 }
Voting implementation
Time Complexity: O(N) where N is the array size
Space Complexity: O(1) Constant space
References