Majority Element
EasyPrompt
Given an array nums of size n, return the majority element.
The majority element is the element that appears more than ⌊n / 2⌋ times. You may assume that the majority element always exists in the array.
Example 1:
Input: nums = [3,2,3]
Output: 3Example 2:
Input: nums = [2,2,1,1,1,2,2]
Output: 2
Constraints:
n == nums.length1 <= n <= 5 * 104-109 <= nums[i] <= 109
Follow-up: Could you solve the problem in linear time and in
O(1) space?Approaches
4 approaches with complexity analysis and trade-offs.
This approach involves iterating through the array for each element and counting its occurrences. If an element's count exceeds n/2, it is returned as the majority element.
Algorithm
- Get the size of the array,
n. - Use an outer loop to iterate from
i = 0ton-1. - Inside the outer loop, select
nums[i]as the candidate and initializecount = 0. - Use an inner loop to iterate from
j = 0ton-1. - Inside the inner loop, if
nums[j]is equal to the candidatenums[i], incrementcount. - After the inner loop completes, check if
count > n / 2. - If the condition is true, return the candidate
nums[i].
Walkthrough
The brute force method uses two nested loops. The outer loop picks an element from the array as a potential candidate for the majority element. The inner loop then iterates through the entire array to count the occurrences of this candidate element.
If the count for any candidate becomes greater than n/2, that candidate is the majority element, and we can return it immediately. Since the problem guarantees that a majority element always exists, this process will always find and return the correct element.
class Solution { public int majorityElement(int[] nums) { int n = nums.length; for (int i = 0; i < n; i++) { int count = 0; for (int j = 0; j < n; j++) { if (nums[j] == nums[i]) { count++; } } if (count > n / 2) { return nums[i]; } } // This part is unreachable given the problem constraints // but is needed for the compiler. return -1; }}Complexity
Time
O(n^2)
Space
O(1)
Trade-offs
Pros
Simple to understand and implement.
Uses constant extra space.
Cons
Highly inefficient, with a quadratic time complexity, making it unsuitable for large datasets.
By sorting the array, the majority element is guaranteed to be at the middle index (n/2). This is because it appears more than n/2 times, so it will occupy the central position after sorting.
Algorithm
- Sort the input array
numsin non-decreasing order. - The majority element is guaranteed to be at the index
n/2. - Return the element
nums[n/2].
Walkthrough
The intuition behind this approach is that if an element occurs more than n/2 times in an array, it will always be the middle element when the array is sorted. Let's consider an array of size n. If we sort it, the element at index n/2 (using 0-based indexing) is the median. Since the majority element appears more than n/2 times, it must occupy this median position.
For example, in [2,2,1,1,1,2,2], n=7. n/2 is 3. After sorting, we get [1,1,1,2,2,2,2]. The element at index 3 is 2, which is the majority element.
import java.util.Arrays; class Solution { public int majorityElement(int[] nums) { Arrays.sort(nums); return nums[nums.length / 2]; }}Complexity
Time
O(n log n)
Space
O(log n) to O(n)
Trade-offs
Pros
Very simple to implement using a built-in sort function.
Cons
Sorting is slower than linear time approaches.
Modifies the original array.
This approach uses a hash map to store the frequency of each element. We iterate through the array once to build the frequency map and then find the element with a count greater than n/2.
Algorithm
- Create a
HashMapto store elements as keys and their frequencies as values. - Iterate through the input array
nums. - For each
num, update its frequency in the hash map. - After the first loop, iterate through the entries of the hash map.
- For each entry, check if its value (frequency) is greater than
n/2. - If it is, return the key corresponding to that entry.
Walkthrough
We can find the majority element by counting the occurrences of each element in the array. A hash map is an ideal data structure for this task, as it provides average O(1) time complexity for insertions and lookups.
We traverse the input array nums. For each element, we update its count in the hash map. If the element is not yet in the map, we add it with a count of 1. If it's already present, we increment its count.
After populating the map, we can iterate through its entries to find which element has a count greater than n/2. Since a majority element is guaranteed to exist, we will surely find one.
import java.util.HashMap;import java.util.Map; class Solution { public int majorityElement(int[] nums) { Map<Integer, Integer> counts = new HashMap<>(); for (int num : nums) { counts.put(num, counts.getOrDefault(num, 0) + 1); } int n = nums.length; for (Map.Entry<Integer, Integer> entry : counts.entrySet()) { if (entry.getValue() > n / 2) { return entry.getKey(); } } // Unreachable code given problem constraints return -1; }}Complexity
Time
O(n)
Space
O(n)
Trade-offs
Pros
Achieves linear time complexity, which is efficient for large arrays.
Cons
Requires extra space proportional to the number of unique elements, which can be up to O(n).
This is an optimal algorithm that finds the majority element in linear time and constant space. It works by maintaining a candidate and a counter, incrementing for the candidate and decrementing for other elements. The majority element's count will prevail.
Algorithm
- Initialize
count = 0andcandidate = null. - Iterate through each element
numin the arraynums. - If
countis 0, setcandidate = num. - If
numis equal tocandidate, incrementcount. Otherwise, decrementcount. - After the loop finishes,
candidatewill hold the majority element. Returncandidate.
Walkthrough
The Boyer-Moore Voting Algorithm is a clever and efficient method for finding the majority element. The core idea is based on the fact that the majority element occurs more than n/2 times. This means it appears more often than all other elements combined.
The algorithm maintains two variables: a candidate for the majority element and a count. We iterate through the array.
- If
countis 0, we choose the current element as the newcandidate. - If the current element is the same as the
candidate, we incrementcount. - If the current element is different, we decrement
count.
Essentially, we are pairing up each occurrence of the majority element with an occurrence of a non-majority element. Since the majority element is more frequent, it will be the last one standing as the candidate.
Because the problem guarantees that a majority element always exists, the final candidate will be the answer. If there was no guarantee, a second pass would be needed to verify if the candidate's count is actually greater than n/2.
class Solution { public int majorityElement(int[] nums) { int count = 0; Integer candidate = null; for (int num : nums) { if (count == 0) { candidate = num; } count += (num == candidate) ? 1 : -1; } return candidate; }}Complexity
Time
O(n)
Space
O(1)
Trade-offs
Pros
Most efficient solution with linear time and constant space.
Solves the follow-up problem directly.
Cons
Can be less intuitive to understand compared to more straightforward approaches like using a hash map or sorting.
Solutions
Solution
public class Solution { public int MajorityElement ( int [] nums ) { int cnt = 0 , m = 0 ; foreach ( int x in nums ) { if ( cnt == 0 ) { m = x ; cnt = 1 ; } else { cnt += m == x ? 1 : - 1 ; } } return m ; } }class Solution { public int majorityElement ( int [] nums ) { int cnt = 0 , m = 0 ; for ( int x : nums ) { if ( cnt == 0 ) { m = x ; cnt = 1 ; } else { cnt += m == x ? 1 : - 1 ; } } return m ; } }/** * @param {number[]} nums * @return {number} */ var majorityElement = function (nums) { let cnt = 0; let m = 0; for (const x of nums) { if (cnt === 0) { m = x; cnt = 1; } else { cnt += m === x ? 1 : -1; } } return m; };class Solution: def majorityElement(self, nums: List[int]) -> int: cnt = m = 0 for x in nums: if cnt == 0: m, cnt = x, 1 else: cnt += 1 if m == x else - 1 return mclass Solution { public: int majorityElement ( vector < int >& nums ) { int cnt = 0 , m = 0 ; for ( int & x : nums ) { if ( cnt == 0 ) { m = x ; cnt = 1 ; } else { cnt += m == x ? 1 : - 1 ; } } return m ; } };Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.