53 在排序数组中查找数字-统计一个数字在排序数组中出现的次数。

输入: nums = [5,7,7,8,8,10], target = 8
输出: 2
排序就是二分无疑。
用了两种方法,第一种相对较差,直接二分之后,找到遍历该target前后有多少个,然后再相加。这样比较一般,时间复杂度不只是二分的logn,而是n,因为最坏的情况还是要遍历一整个数组。

第二种方法是分别找到重复数字的最前面的数字的序号和最后面的数字的序号,再进行相减得到数目。二分的变体,依旧可以找到最前和最后的!

class Solution(object):
    sign = False #全局变量,原因是下面可能分不清是没找到得
    #到的0,还是找到的位置是0
    def erfen(self, nums, target):
        min = 0
        max = len(nums) - 1
        if nums[max] < target or nums[min] > target:
            return False
        while min <= max:
            mid = (max + min) // 2
            if nums[mid] > target:
                max = mid - 1
            if nums[mid] < target:
                min = mid + 1
            if nums[mid] == target:
                Solution.sign = True
                return mid
        return False

    def search(self, nums, target):
        if not nums:
            return 0
        m = self.erfen(nums, target)
        a = 0
        if Solution.sign:
            n = m
            m -= 1
            while nums[n] == target : # 这种往前和往后查找的办法可能遇到最坏的时间复杂度也是n,所以并不是好的办法,下面继续优化!!
                n += 1
                a += 1
                if  n == len(nums):
                    break
            while m >= 0 and nums[m] == target :
                m -= 1
                a += 1
                if  m == -1:
                    break
        return a

第二种:也可以把first和last函数合并成一个。

class Solution(object):  # 改成两个,一个查找第一个出现的序号,一个查找最后一个出现的序号。

    def search(self, nums, target):
        # 二分的思想改进     # 记住不用递归,while在此不需要
        if not nums:
            return 0
        self.sign_first = 0
        self.sign_last = 0

        def first(nums, max, min):
            while min <= max:
                mid = (max + min) // 2
                if nums[mid] > target:
                    max = mid - 1
                elif nums[mid] < target:
                    min = mid + 1
                elif nums[mid] == target:
                    self.sign_first = 1
                    if mid == 0 or nums[mid - 1] != target:
                        return mid
                    else:
                        max = mid - 1

        def last(nums, max, min):
            while min <= max:
                mid = (max + min) // 2  # 可以简化:fist保留
                if nums[mid] > target:
                    max = mid - 1
                elif nums[mid] <= target:
                    min = mid + 1
                elif nums[mid] == target:
                    self.sign_last = 1
                    if mid == len(nums) - 1 or nums[mid + 1] != target:
                        return mid
                    else:
                        min = mid + 1

        max = len(nums) - 1
        min = 0
        mid_first = first(nums, max, min)
        mid_last = last(nums, max, min)

        if not self.sign_first:
            return 0

        if mid_first == mid_last:
            return 1
        else:
            return mid_last - mid_first + 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值