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

posted @ 2019-12-18 14:03  包子模拟面试  阅读(164)  评论(0编辑  收藏  举报