Problem
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.
Examples
Example 1:
Input: nums = [3,2,3]
Output: [3]
Example 2:
Input: nums = [1]
Output: [1]
Example 3:
Input: nums = [1,2]
Output: [1,2]
Solution
Method 1 - Using a Hashmap Counter
Here is the approach:
- A
HashMap
is used to count the occurrences of each element in the array. - A second loop checks which elements appear more than
n / 3
times and adds them to the result list.
Code
Java
public class Solution {
public List<Integer> majorityElement(int[] nums) {
Map<Integer, Integer> countMap = new HashMap<>();
// Count the occurrences of each element
for (int num : nums) {
countMap.put(num, countMap.getOrDefault(num, 0) + 1);
}
List<Integer> result = new ArrayList<>();
int threshold = nums.length / 3;
// Collect the elements that appear more than n/3 times
for (Map.Entry<Integer, Integer> entry : countMap.entrySet()) {
if (entry.getValue() > threshold) {
result.add(entry.getKey());
}
}
return result;
}
public static void main(String[] args) {
Solution solution = new Solution();
int[] nums = {3, 2, 3};
System.out.println(solution.majorityElement(nums)); // Output: [3]
int[] nums2 = {1, 1, 1, 3, 3, 2, 2, 2};
System.out.println(solution.majorityElement(nums2)); // Output: [1, 2]
}
}
Python
class Solution:
def majorityElement(self, nums):
count_map = {}
# Count the occurrences of each element
for num in nums:
count_map[num] = count_map.get(num, 0) + 1
result = []
threshold = len(nums) // 3
# Collect the elements that appear more than n/3 times
for num, count in count_map.items():
if count > threshold:
result.append(num)
return result
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(n)
Method 2 - Voting Algorithm with 2 Counters
This approach is similar to Majority Element 1 - with n by 2 definition.
Code
Java
public class Solution {
public List<Integer> majorityElement(int[] nums) {
var result = new ArrayList<Integer>();
Integer candidate1 = null, candidate2 = null;
int count1 = 0, count2 = 0;
// Step 1: Find potential candidates
for (var num : nums) {
if (Objects.equals(candidate1, num)) {
count1++;
} else if (Objects.equals(candidate2, num)) {
count2++;
} else if (count1 == 0) {
candidate1 = num;
count1 = 1;
} else if (count2 == 0) {
candidate2 = num;
count2 = 1;
} else {
count1--;
count2--;
}
}
// Step 2: Validate the candidates
count1 = count2 = 0;
for (var num : nums) {
if (Objects.equals(candidate1, num)) {
count1++;
} else if (Objects.equals(candidate2, num)) {
count2++;
}
}
if (count1 > nums.length / 3) {
result.add(candidate1);
}
if (count2 > nums.length / 3) {
result.add(candidate2);
}
return result;
}
}
Python
class Solution:
def majorityElement(self, nums):
candidate1 = candidate2 = None
count1 = count2 = 0
# Step 1: Find potential candidates
for num in nums:
if candidate1 == num:
count1 += 1
elif candidate2 == num:
count2 += 1
elif count1 == 0:
candidate1, count1 = num, 1
elif count2 == 0:
candidate2, count2 = num, 1
else:
count1 -= 1
count2 -= 1
# Step 2: Validate the candidates
count1 = count2 = 0
for num in nums:
if num == candidate1:
count1 += 1
elif num == candidate2:
count2 += 1
result = []
if count1 > len(nums) // 3:
result.append(candidate1)
if count2 > len(nums) // 3:
result.append(candidate2)
return result
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(1)