【lc刷题】169/229 求众数/求众数 II_Day37(106-107/300)

106-107/300

求众数

  1. 求众数
    给定一个大小为 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

  1. 求众数 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)

所以玩儿消消乐满足要求!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值