106-107/300
求众数
- 求众数
给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在众数。
示例 1:
输入: [3,2,3]
输出: 3
示例 2:
输入: [2,2,1,1,1,2,2]
输出: 2
简单题,不多说。
仔细学习了generator之后,觉得自己写的代码高大上了起来~
笔记心得放在了这里:python generator函数与yield,next的使用 以及如何计算for循环调用次数
class Solution:
def majorityElement(self, nums: List[int]) -> int:
mydict = collections.Counter(nums)
return next(num for num, c in mydict.items() if c > (len(nums)/2) )
class Solution:
def majorityElement(self, nums: List[int]) -> int:
return next(num for num in set(nums) if nums.count(num) >(len(nums)/2) )
求众数 II
- 求众数 II
给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。
说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1)。
示例 1:
输入: [3,2,3]
输出: [3]
示例 2:
输入: [1,1,1,3,3,2,2,2]
输出: [1,2]
time: O(n),space: O(1) 这个要求有点过啊,
我们来算上面简单题第一种解法collections.Counter, space: O(n); for loop time: O(n)
第二种解法set(nums), space O(n); for loop + nums.count(n), time: O(n*n)
我们是不是可以把第一种解法的Counter的space变成constant,其他的不变就ok了呢:
先考虑list里有3种及3种以上的num,目标num的次数>1/3,说明num并不是湮没于众nums里的。
当Counter集齐3个,消消乐,消到最后剩下的,就是我们要的。
但list里可能有3种以下的num,这时候玩儿不了消消乐了,所以只好用num.count()
class Solution:
def majorityElement(self, nums: List[int]) -> List[int]:
mydict = collections.Counter()
for n in nums:
mydict[n] += 1
if len(mydict) == 3:
mydict -= collections.Counter(set(mydict))
return [ _ for _ in mydict if nums.count(_) > len(nums)/3]
再来算一下时间空间复杂度, 消消乐这步不超过len=3,space从O(n)缩减为O(3)->O(1); for loop + nums.count 也就是O(3*n) ->O(n)
所以玩儿消消乐满足要求!