Challenges • Asked about 5 years ago by abrar
the solution mentinons sorting (O(nlogn)).
instead we can use dictionary/hashmap
sorting in O(n), n = number of elements
searching for majority element O(m) at worst case, m = number of keys of dictionary
where m n:
return key`
Link to problem: Majority Element.
Your hashmap approach is linear time, but a couple of nits:
Example:
def majority_element(nums):
half = len(nums) // 2
counts = {}
for x in nums:
c = counts.get(x, 0) + 1
counts[x] = c
if c > half:
return x
return None # if not guaranteed to exist
If you want O(1) extra space, use Boyer–Moore:
def majority_element(nums):
cand, cnt = None, 0
for x in nums:
if cnt == 0:
cand, cnt = x, 1
elif x == cand:
cnt += 1
else:
cnt -= 1
return cand # verify with a second pass if majority isn't guaranteed
collections.Counter also makes the dict approach concise:
from collections import Counter
def majority_element(nums):
half = len(nums) // 2
val, freq = Counter(nums).most_common(1)[0]
return val if freq > half else None
Side note: if the values are only 0/1/2 and you’re sorting them, that’s where the Dutch National Flag problem applies for O(n) time and O(1) space, but that’s a different task than finding a majority.
Good discussion. A couple clarifications and why the editorial shows sort:
If you want O(1) extra space, Boyer–Moore is the go-to:
def majority_element(nums):
cand, cnt = None, 0
for x in nums:
if cnt == 0:
cand, cnt = x, 1
elif x == cand:
cnt += 1
else:
cnt -= 1
return cand
We often list multiple approaches (similar to Trapping Rain Water) to highlight time/space trade-offs: sort for simplicity/space, hashmap for linear time, Boyer–Moore for linear time and constant space.
abrar, a few tighten-ups based on the thread:
def majority_element(nums):
half = len(nums) // 2
counts = {}
for x in nums:
c = counts.get(x, 0) + 1
counts[x] = c
if c > half:
return x