Leetcode Majority Element python 多种思路求集合中出现最多次数的值 提升计算机思维

Leetcode 169题 Majority Element

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exist in the array.

Example 1:

Input: [3,2,3]
Output: 3

Example 2:

Input: [2,2,1,1,1,2,2]
Output: 2

题目大意,求集合中出现次数最多的值,且此值出现次数大于总数的二分之一。 且次数一定存在。

这道题我在学习的时候给了我很多的启发。给了我在计算机思维上面有了很大的提点。求众数,随便一想,遍历、计数、返回。 觉得很简单,其实不然。

思路一:
最简单的思路,遍历、计数、返回值。 这里用到了哈希表。python中用字典表示。 字典的底层原理就是哈希表。
这里牵扯到.get的用法。 .get获取字典中某个键的值,若没有这个键返回None,若.get中添加值,则返回这个值。 字典中的计数频率高。

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        counts ={}
        for i in nums:
            counts[i] = counts.get(i,0)+1 
            #第一次计数肯定没有值,不能让其返回None,所以设置为0,再加1,则第一次统计为1.
            if counts[i] > len(nums)/2:
                return i

同理,这个应该归在方法一中。同样是计数。 利用集合中的.count方法,直接计数。 也挺方便。
操作过程中有一个问题。因为本来nums就被定义为List[int],所以本应该可以直接在nums中遍历循环,可以测试时通过,上交时却超时。 必须要先把nums取集合操作(set)之后,才能不超时,不知道为什么,还请大佬指导。对比代码如下

#测试通过,上交超时代码。
class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        for i in nums:
            if nums.count(i) > len(nums)/2:
                return i

VS.

#取集合操作(set)代码。测试,上交均通过。
class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        set_nums = set(nums)
        for i in set_nums:
            if nums.count(i) > len(nums)/2:
                return i

思路二:
先把数字集合排序,因为要求的众数大于总数的二分之一且一定存在。所以最中间的那个数肯定是要求的众数。很巧妙!
上代码。

class Solution(object):
    def majorityElement(self, nums):
        nums.sort()
        return nums[int(len(nums)/2)] #int取整。

实践过程中,如果数字集合有奇数个,还牵扯到取整的问题。
两个方法:1.四舍五入round()向上取整 2. int()向下取整。
因为数字集合从0开始计算,所以实际上int()向下取的整才是中间的值。

思路三:
随机抽一个数,判断它出现的次数是否大于二分之一。因为众数大于二分之一,所以理论上来说最多取两次。 最差则取一半加一的次数。理论效率比全部统计次数高,实际存在最差的情况。

class Solution(object):
    def majorityElement(self, nums):
        import random
        while nums:
            r = random.choice(nums)
            if nums.count(r) > len(nums)/2:
                return r

运行效率在数字集合大时得以体现。

思路三: 应该叫做摩尔投票(Moore Voting Algorithm)。
每次都找出一对不同的元素,从数组中删掉,直到数组为空或只有一种元素。 不难证明,如果存在元素e出现频率超过半数,那么数组中最后剩下的就只有e。
这个思路很巧妙,有点像异或用法,其实用了一个类似于异或的交换率,仔细想想就相同了。
上代码。

class Solution(object):
    def majorityElement(self, nums):
        major = count = 0
        for i in nums:
            if count == 0:
                major = i
                count = 1
            else:
                count += 1 if major==i else -1 #此处的= =做对比作用,不是赋值,否则就很容易迷。
        return major

很巧妙!

其他的思路有点儿不太适合了,都有些为赋新词强说愁的感觉。

2020/03/25
写了三个思路,耗费了我两个小时的时间。心痛。
疫情中的英国,加油!

发布了20 篇原创文章 · 获赞 1 · 访问量 795

猜你喜欢

转载自blog.csdn.net/weixin_43860294/article/details/105106976
今日推荐