26. Majority Element II

βœ… GFG solution to the Majority Element II problem: find all elements appearing more than n/3 times using Boyer-Moore Majority Vote algorithm. πŸš€

The problem can be found at the following link: πŸ”— Question Link

🧩 Problem Description

You are given an array of integer arr[] where each number represents a vote to a candidate. Return the candidates that have votes greater than one-third of the total votes. If there's not a majority vote, return an empty array.

Note: The answer should be returned in an increasing format.

πŸ“˜ Examples

Example 1

Input: arr[] = [2, 1, 5, 5, 5, 5, 6, 6, 6, 6, 6]
Output: [5, 6]
Explanation: 5 occurs 4 times and 6 occurs 5 times. Both appear more than n/3 = 11/3 = 3.67 times.
Hence, both 5 and 6 are majority elements.

Example 2

Input: arr[] = [1, 2, 3, 4, 5]
Output: []
Explanation: The total number of votes are 5. No candidate occurs more than floor(5/3) = 1 time.
Since we need elements appearing more than n/3 times, no element qualifies.

πŸ”’ Constraints

  • $1 \le \text{arr.size()} \le 10^6$

  • $1 \le \text{arr}[i] \le 10^5$

βœ… My Approach

The optimal approach uses the Boyer-Moore Majority Vote Algorithm extended for finding elements appearing more than n/3 times:

Boyer-Moore Voting Algorithm (Extended)

  1. Key Insight:

    • At most 2 elements can appear more than n/3 times in an array.

    • We maintain two candidates and their counts during the voting phase.

  2. Phase 1 - Candidate Selection:

    • Initialize two candidates a and b with different values, and their counts ca and cb.

    • For each element x:

      • If x equals candidate a, increment ca

      • Else if x equals candidate b, increment cb

      • Else if ca is 0, set a = x and ca = 1

      • Else if cb is 0, set b = x and cb = 1

      • Else decrement both ca and cb (voting against both candidates)

  3. Phase 2 - Verification:

    • Reset counts and verify if the selected candidates actually appear more than n/3 times.

    • Count actual occurrences of candidates a and b in the array.

  4. Result Formation:

    • Add candidates to result if their count > n/3.

    • Sort the result for increasing order output.

πŸ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(n), where n is the size of the array. We make two passes through the array - one for candidate selection and one for verification.

  • Expected Auxiliary Space Complexity: O(1), as we only use a constant amount of additional space for storing two candidates and their counts.

πŸ§‘β€πŸ’» Code (C++)

⚑ View Alternative Approaches with Code and Analysis

πŸ“Š 2️⃣ Hash Map Frequency Count

πŸ’‘ Algorithm Steps:

  1. Count frequency of each element using unordered_map

  2. Filter elements with count > n/3

  3. Sort result for consistent output

  4. Single pass solution with O(n) space

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n + k log k) where k is unique elements

  • Auxiliary Space: πŸ’Ύ O(n) - for hash map

βœ… Why This Approach?

  • Simple to understand and implement

  • Works well for small datasets

  • Good when memory is not a constraint

πŸ“Š 3️⃣ Sorting Based Approach

πŸ’‘ Algorithm Steps:

  1. Sort the array to group identical elements

  2. Count consecutive occurrences

  3. Check if count exceeds n/3 threshold

  4. Collect qualifying elements

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n log n) - for sorting

  • Auxiliary Space: πŸ’Ύ O(1) - constant extra space

βœ… Why This Approach?

  • Space optimal solution

  • Modifies input array (saves space)

  • Good for memory-constrained environments

πŸ“Š 4️⃣ Divide and Conquer Approach

πŸ’‘ Algorithm Steps:

  1. Recursively divide array into two halves

  2. Find majority candidates from both halves

  3. Merge and validate candidates

  4. Return elements exceeding n/3 threshold

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n log n) - divide and conquer

  • Auxiliary Space: πŸ’Ύ O(log n) - recursion stack

βœ… Why This Approach?

  • Demonstrates divide and conquer paradigm

  • Good for parallel processing

  • Educational value for algorithm design

πŸ†š πŸ” Comparison of Approaches

πŸš€ Approach

⏱️ Time Complexity

πŸ’Ύ Space Complexity

βœ… Pros

⚠️ Cons

πŸ” Boyer-Moore Voting

🟒 O(n)

🟒 O(1)

πŸš€ Optimal time and space

πŸ”§ Complex logic to understand

πŸ—‚οΈ Hash Map Frequency

🟑 O(n + k log k)

πŸ”΄ O(n)

πŸ”§ Simple and intuitive

πŸ’Ύ High space complexity

πŸ“Š Sorting Based

πŸ”΄ O(n log n)

🟒 O(1)

⚑ Space optimal

⏰ Slower due to sorting

πŸŒ€ Divide and Conquer

πŸ”΄ O(n log n)

🟑 O(log n)

πŸŽ“ Educational value

πŸ”„ Complex implementation

πŸ† Best Choice Recommendation

🎯 Scenario

πŸŽ–οΈ Recommended Approach

πŸ”₯ Performance Rating

⚑ Optimal performance required

πŸ₯‡ Boyer-Moore Voting

β˜…β˜…β˜…β˜…β˜…

πŸ“Š Simple implementation needed

πŸ₯ˆ Hash Map Frequency

β˜…β˜…β˜…β˜…β˜†

🎯 Memory constrained environment

πŸ₯‰ Sorting Based

β˜…β˜…β˜…β˜†β˜†

πŸš€ Learning algorithm design

πŸ… Divide and Conquer

β˜…β˜…β˜…β˜†β˜†

β˜• Code (Java)

🐍 Code (Python)

🧠 Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: πŸ“¬ Any Questions?. Let's make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Visitor counter

Last updated