169.多数元素(摩尔投票+分治法)

多数元素(python年度更新版)

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
输入:[3,2,3]
输出:3

来源:力扣(LeetCode)
链接:多数元素

摩尔投票法(会中文就能理解)

本题的思路首先想到的是摩尔投票法,比如说多国混战,n人参战,存在一个国家有多于n/2的人参战时,这个国家必然获得最后的胜利。

那么我们模拟这个混战的过程,用夺旗来比喻。

时间复杂度为O(n),空间复杂度为O(1)

class Solution(object):
    def majorityElement(self, nums):
    	#无人参战时,直接返回。
        if not nums:
            return
        #有人参战时,先有一方夺旗
        targernum = nums[0]
        #此时有1个人守旗
        cnt = 1
        #开始进行夺旗
        for i in nums[1:len(nums)]:
        #当是自己人时加入守旗,人数加1
            if targernum == i:
                cnt += 1
       	#否则进行夺旗,夺旗者进行一次攻击
            else:
                cnt -= 1
        #守旗者受攻击后若人数为0时则夺旗者夺旗成功
            if cnt == 0:
                targernum = i
                cnt = 1
        return targernum

分治法

首先,a是数组nums的众数时,那么当nums分为nums[left,mid],nums[mid+1,right]时,a必是其中之一的众数,那么我们去寻找a时,只需要找到子数组的众数,如果相等则直接返回,如果不相等那么则比较两个众数在nums中出现的次数,然后返回这个较大的值。

时间复杂度:O(nlogn)
空间复杂度:O(logn)

class Solution(object):
    def majorityElement(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        left = 0
        right = len(nums)-1
        def majorityElement_rec(left,right):
            if left == right:
                return nums[left]
            mid = (left + right)/2
            #找出左边的众数
            left = majorityElement_rec(left,mid)
            #找出右边的众数
            right = majorityElement_rec(mid+1,right)
            #如果相等则直接返回这个众数
            if left == right:
                return left
            #否则的话比较二者出现的次数
            left_count = nums.count(left)
            right_count = nums.count(right)
            if left_count > right_count:
                return left
            else:
                return right
        return majorityElement_rec(left,right)

这题用分治显然没必要,图一乐了解就好。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值