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:

  • 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)

Reference

A Linear Time Majority Vote Algorithm