Difficulty: Medium
Majority
Element II
Given an
integer array of size n, find all elements that appear more
than ⌊n/3⌋ times.
The algorithm should run in linear time and in O(1) space.
Runtime Analysis:
Runtime: O(n)
Algorithmic Approach:
This problem can be solved using the Boyer-Moore majority vote algorithm.
Before we are digging into this algorithm, let's see one basic observation:
How many majority elements at most in this problem?
Answer: Two.
Explanation: At most there are 3 elements appear exactly n/3 times. So for more
than n/3 times, at most there are 2 elements.
Now we discuss the Moore majority vote algorithm. Quoted from wiki:
"The algorithm is carried out in two steps:
1. Eliminate all elements except one.
Iterating through the array of numbers, maintain a current candidate and a
counter initialized to 0. With the current element x in iteration, update the
counter and (possibly) the candidate:
If the counter is 0, set the current candidate to x and the counter to 1. If
the counter is not 0, increment or decrement the counter based on whether x is
the current candidate.
2. Determine if the remaining element is a valid majority element.
With the candidate acquired in step 1, iterate through the array of numbers and
count its occurrences. Determine if the result is more than half of the
sequence's length. If so, the candidate is the majority. Otherwise, the
sequence doesn't contain a majority."
The key idea of this algorithm is "decrement" of the counter when new
elements are different from all the current candidates. This
"decrement" operation is to cancel out the elements
that do not appear most times in the array. Therefore, after one scan, the
candidates are the elements which appear most of the times. The last step
is to check if these candidates are satisfied with the condition of more than
n/3 times.
Java Code:
public List<Integer> majorityElement(int[] nums) {
if (nums == null || nums.length == 0)
return new ArrayList<Integer>();
List<Integer> result = new ArrayList<Integer>();
int number1 = nums[0], number2 = nums[0];
int count1 = 0, count2 = 0, len = nums.length;
for (int i = 0; i < len; i++) {
if (nums[i] == number1)
count1++;
else if (nums[i] == number2)
count2++;
else if (count1 == 0) {
number1 = nums[i];
count1 = 1;
}
else if (count2 == 0) {
number2 = nums[i];
count2 = 1;
}
else {
count1--;
count2--;
}
}
count1 = 0;
count2 = 0;
for (int i = 0; i < len; i++) {
if (nums[i] == number1)
count1++;
else if (nums[i] == number2)
count2++;
}
if (count1 > len / 3)
result.add(number1);
if (count2 > len / 3)
result.add(number2);
return result;
}
Runtime: O(n)
Before we are digging into this algorithm, let's see one basic observation:
How many majority elements at most in this problem?
Answer: Two.
Explanation: At most there are 3 elements appear exactly n/3 times. So for more than n/3 times, at most there are 2 elements.
Now we discuss the Moore majority vote algorithm. Quoted from wiki:
"The algorithm is carried out in two steps:
1. Eliminate all elements except one.
Iterating through the array of numbers, maintain a current candidate and a counter initialized to 0. With the current element x in iteration, update the counter and (possibly) the candidate:
If the counter is 0, set the current candidate to x and the counter to 1. If the counter is not 0, increment or decrement the counter based on whether x is the current candidate.
2. Determine if the remaining element is a valid majority element.
With the candidate acquired in step 1, iterate through the array of numbers and count its occurrences. Determine if the result is more than half of the sequence's length. If so, the candidate is the majority. Otherwise, the sequence doesn't contain a majority."
The key idea of this algorithm is "decrement" of the counter when new elements are different from all the current candidates. This "decrement" operation is to cancel out the elements that do not appear most times in the array. Therefore, after one scan, the candidates are the elements which appear most of the times. The last step is to check if these candidates are satisfied with the condition of more than n/3 times.
Java Code:
public List<Integer> majorityElement(int[] nums) {
if (nums == null || nums.length == 0)
return new ArrayList<Integer>();
List<Integer> result = new ArrayList<Integer>();
int number1 = nums[0], number2 = nums[0];
int count1 = 0, count2 = 0, len = nums.length;
for (int i = 0; i < len; i++) {
if (nums[i] == number1)
count1++;
else if (nums[i] == number2)
count2++;
else if (count1 == 0) {
number1 = nums[i];
count1 = 1;
}
else if (count2 == 0) {
number2 = nums[i];
count2 = 1;
}
else {
count1--;
count2--;
}
}
count1 = 0;
count2 = 0;
for (int i = 0; i < len; i++) {
if (nums[i] == number1)
count1++;
else if (nums[i] == number2)
count2++;
}
if (count1 > len / 3)
result.add(number1);
if (count2 > len / 3)
result.add(number2);
return result;
}
No comments:
Post a Comment