Given an integer array of size n
, find all elements that appear more than ⌊ n/3 ⌋
times.
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]
Constraints:
1 <= nums.length <= 5 * 104
-109 <= nums[i] <= 109
Follow up: Could you solve the problem in linear time and in O(1)
space?
This problem asks to find all elements in an array that appear more than ⌊n/3⌋ times, where n is the length of the array. The solutions presented utilize Boyer-Moore Voting Algorithm's core idea, adapted to handle potentially two majority elements instead of just one.
Algorithm:
Initialization: We maintain two candidate elements, m1
and m2
, and their respective counts, n1
and n2
. Initially, n1
and n2
are 0, and m1
and m2
can be initialized to arbitrary values (the code uses 0 and 1).
Iteration: We iterate through the input array nums
. For each element m
:
m
is equal to m1
, increment n1
.m
is equal to m2
, increment n2
.m
is different from both m1
and m2
:
n1
is 0, set m1
to m
and n1
to 1.n1
is not 0 and n2
is 0, set m2
to m
and n2
to 1.n1
nor n2
is 0, decrement both n1
and n2
.Verification: After the iteration, m1
and m2
are potential candidates. We need to verify if they actually appear more than ⌊n/3⌋ times in the array. This is done by iterating through the array again and counting occurrences of m1
and m2
.
Result: Finally, we return a list containing only those candidates (m1
and/or m2
) that satisfy the frequency condition.
Time Complexity Analysis:
The algorithm iterates through the input array nums
twice. Therefore, the time complexity is O(n), where n is the length of the array.
Space Complexity Analysis:
The algorithm uses a constant amount of extra space to store the candidate elements and their counts. The space used for the final result list is proportional to the number of majority elements (at most 2). Thus, the space complexity is O(1) (constant space).
Code Explanation (Python Example):
class Solution:
def majorityElement(self, nums: List[int]) -> List[int]:
n1 = n2 = 0 # Counters for candidate elements
m1, m2 = 0, 1 # Candidate elements (initial values are arbitrary)
for m in nums:
if m == m1:
n1 += 1
elif m == m2:
n2 += 1
elif n1 == 0: # If no first candidate, assign m
m1, n1 = m, 1
elif n2 == 0: # If no second candidate, assign m
m2, n2 = m, 1
else: # If both candidates exist, decrement counters
n1 -= 1
n2 -= 1
# Verify candidates by recounting
return [m for m in [m1, m2] if nums.count(m) > len(nums) // 3]
The Java, C++, Go, C#, and PHP code implement the same algorithm with minor syntax differences. The key idea—the two-candidate Boyer-Moore voting variation—remains consistent across all implementations.