You are given an integer array nums of size n, find all elements that appear more than ⌊ n/3 ⌋ times. You can return the result in any order.
Example 1:
Input: nums = [5,2,3,2,2,2,2,5,5,5]
Output: [2,5]Example 2:
Input: nums = [4,4,4,4,4]
Output: [4]Example 3:
Input: nums = [1,2,3]
Output: []Constraints:
1 <= nums.length <= 50,000.-1,000,000,000 <= nums[i] <= 1,000,000,000Follow up: Could you solve the problem in linear time and in O(1) space?
Elements appearing more than n/3 times are rare. There can be at most two such elements. For each unique element, we count its occurrences and check if it exceeds n/3. We use a set to avoid adding duplicates to the result.
num in the array:num appears.n / 3, add it to the result set.After sorting, identical elements are grouped together. We can scan through and count consecutive runs of each element. If a run's length exceeds n/3, we add that element to our result. This approach avoids the nested loops of brute force.
i and j to identify consecutive groups of equal elements.j - i > n / 3, add the element to the result.i to j and repeat until the array is exhausted.We can count each element's frequency in a single pass using a hash map. Then we iterate through the map and collect all elements whose count exceeds n/3. This trades space for time compared to the brute force approach.
n / 3, add the element to the result.The Boyer-Moore algorithm extends to finding up to two majority elements. We maintain two candidates with their counts. When we see a candidate, we increment its count. When we see a different element and both counts are positive, we decrement both. When a count is 0, we replace that candidate. After one pass, we verify the candidates by counting their actual occurrences.
num1, num2 and their counts cnt1, cnt2 to 0.num1, increment cnt1.num2, increment cnt2.cnt1 == 0, set num1 = num and cnt1 = 1.cnt2 == 0, set num2 = num and cnt2 = 1.n / 3 to the result.class Solution:
def majorityElement(self, nums: List[int]) -> List[int]:
n = len(nums)
num1 = num2 = -1
cnt1 = cnt2 = 0
for num in nums:
if num == num1:
cnt1 += 1
elif num == num2:
cnt2 += 1
elif cnt1 == 0:
cnt1 = 1
num1 = num
elif cnt2 == 0:
cnt2 = 1
num2 = num
else:
cnt1 -= 1
cnt2 -= 1
cnt1 = cnt2 = 0
for num in nums:
if num == num1:
cnt1 += 1
elif num == num2:
cnt2 += 1
res = []
if cnt1 > n // 3:
res.append(num1)
if cnt2 > n // 3:
res.append(num2)
return resThis variation uses a hash map to track candidates instead of fixed variables. We allow at most 2 elements in the map. When a third element tries to enter, we decrement all counts and remove elements with count 0. This generalizes the Boyer-Moore approach and can be extended to find elements appearing more than n/k times.
0.n / 3.class Solution:
def majorityElement(self, nums: List[int]) -> List[int]:
count = defaultdict(int)
for num in nums:
count[num] += 1
if len(count) <= 2:
continue
new_count = defaultdict(int)
for num, c in count.items():
if c > 1:
new_count[num] = c - 1
count = new_count
res = []
for num in count:
if nums.count(num) > len(nums) // 3:
res.append(num)
return resThe Boyer-Moore voting algorithm only identifies candidates that might appear more than n/3 times. After the first pass, you must verify each candidate by counting its actual occurrences. Skipping this step returns incorrect results when candidates do not actually exceed the threshold. This verification pass is essential, not optional.
The problem asks for elements appearing more than n/3 times, meaning strictly greater than (>), not greater than or equal to (>=). Using count >= n/3 includes elements that appear exactly n/3 times, which is incorrect. Be precise with the comparison operator.
When implementing Boyer-Moore with two candidates, the order of conditions matters. You must first check if the current element matches an existing candidate before checking if a slot is empty. If you check for empty slots first, you might assign the same element to both candidate slots, wasting one slot and missing potential majority elements.