【剑指offer】29. 数组中出现超过一半的数字(python)

题目描述

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

思路

《剑指offer》P163

  • 方法一:
    使用快排的思想,先随机选择一个数字,进行一趟排序,使得该数字左边的数都比其小,右边的数都比其大,然后判断该数字的index是否位于数组中间,如果是,则计算出现的次数,大于长度的一半则返回该数。否则,如果index>mid则将左边的数字再排序,如果index<mid则将右边的数字再排序。

    时间复杂度 O(NlogN)

  • 方法二:
    遍历一趟数组,保存两个值:一个是当前的数字n,一个是次数cnt。如果当前数字与n相等,则cnt++,不相等则cnt--,如果cnt减为0,则将n重新置为当前的数字,cnt=1
    遍历完毕后,n的值即为候选数,然后再判断该数在数组中的次数。

code

方法一:

# -*- coding:utf-8 -*-
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        mid = len(numbers) / 2
        index = self.Parition(numbers, 0, len(numbers) - 1)
        while index != mid:
            if index < mid:
                index = self.Parition(numbers, index + 1, len(numbers) - 1)
            else:
                index = self.Parition(numbers, 0, index - 1)
        if self.CheckNumber(numbers, numbers[index]):
            return numbers[index]
        else:
            return 0
        
        
    def Parition(self, arr, low, high):
        index = low - 1
        for i in range(low, high):
            if arr[i] <= arr[high]:
                index += 1
                arr[i], arr[index] = arr[index], arr[i]
        index += 1
        arr[index], arr[high] = arr[high], arr[index]
        return index
    
    def CheckNumber(self, arr, number):
        cnt = 0
        for n in arr:
            if n == number:
                cnt += 1
        if cnt * 2 > len(arr):
            return True
        return False

方法二

# -*- coding:utf-8 -*-
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        if not numbers:
            return 0
        cnt = 1
        n = numbers[0]
        for x in numbers[1:]:
            if x == n:
                cnt += 1
            else:
                cnt -= 1
                if cnt == 0:
                    n = x
                    cnt += 1
        if self.CheckNumber(numbers, n):
            return n
        else:
            return 0
    
    def CheckNumber(self, arr, number):
        cnt = 0
        for n in arr:
            if n == number:
                cnt += 1
        if cnt * 2 > len(arr):
            return True
        return False
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值