二分法查找+牛客-缺失数字

二分法之查找最接近目标数的数

def erfen(nums, target):
    left = 0
    right = len(nums) - 1
    while left < right:
        mid = (left+right)//2
        if nums[mid] > target:
            right = mid - 1
        elif nums[mid] <= target:
            left = mid + 1
    return nums[:left] + [target] + nums[left:]

二分法要注意的点是 分的是下标,然后注意+1更新,因为判断之后,如果不等于mid,则下一个范围不用包含上一个mid。
注意一上来先排除特殊情况,最大小值。

def erfen1(nums,a):
    min = 0
    max = len(nums) - 1
    if a > nums[max] or a < nums[min]:
        return []
    while max >= min:
        mid = int((max+min)/2)
        if a == nums[mid]:
            return mid
        elif a > nums[mid]:
            min = mid+1
        else:
            max = mid-1
    return []

print(erfen1([3,4,5,6,7,8,9],9))
def binarysearch(s, target):
    min = 0
    max = len(s)
    if s[min] > target or s[max] < target:
        return
    while min < max:
        mid = (min + max)//2
        if s[mid] < target:
            min = mid + 1
        elif s[mid] > target:
            max = mid - 1
        else:
            return mid
    return

时间复杂度是O(logn)
如何看呢,原来的长度是n,每一次划分都是除以2,最后的长度是1,所以等式在这里插入图片描述
x代表的是二分的次数。x = log(n) 。2在这里可以不写,与5n的系数不写的道理一样。

在这里插入图片描述
边界问题是模糊的点!注意!

class Solution(object):
    def minArray(self, numbers):
        """
        :type numbers: List[int]
        :rtype: int  使用min 和 mid比较不太好,因为这个变化规律可能出现在后半部分递增的数组里
        """
        if not numbers:
            return 
        min = 0
        max = len(numbers)-1
        # mid = (min + max)//2


        while min <= max:
            mid = min + (max-min)//2
            if numbers[max] < numbers[mid]:
                min = mid + 1
            elif numbers[max] > numbers[mid]:
                max = mid 
            else:
                max -= 1  # [2,2,2,2,2,1,2,2,2,2] 
                #当遇到相等的时候,可以往左移动一位,活起来;
                #或者当min==max的时候,跳出循环。

        return numbers[min]

缺失数字

在这里插入图片描述

class Solution:
    def solve(self , a ):
        # write code here
        # partition 如果该位置的数大于序号,说明前面缺失,如果等于序号,说明不缺失
        left = 0
        right = len(a) - 1
        while left <= right:
            mid = (left + right) // 2
            if a[mid] > mid:
                right = mid - 1
            else:
                left = mid + 1
        return left # right + 1最后必须right+1,因为最后一个判断还减去1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值