品味二分查找

二分查找细节很多啊!!!

一、寻找一个数(基本的二分搜索)

int binarySearch(int[] nums, int target) {
    int left = 0; 
    int right = nums.length - 1; // 注意 双闭区间

    while(left <= right) { //[left,right]区间内元素为空时返回.比如[3,2]时,返回
        int mid = left + (right - left) / 2; //防止溢出
        if(nums[mid] == target)
            return mid; 
        else if (nums[mid] < target)
            left = mid + 1; // 注意 mid位置已经搜索过了,所以为mid+1
        else if (nums[mid] > target)
            right = mid - 1; // 注意 同上,故为mid-1
    }
    return -1;
}

思考:

1、为什么 while 循环的条件中是 <=,而不是 <?
2、为什么 left = mid + 1,right = mid - 1?我看有的代码是 right = mid 或者 left = mid,没有这些加加减减,到底怎么回事,怎么判断?

二、寻找左/右侧边界的二分搜索

class Solution:
    def search(self, nums, target) -> int:
        '''寻找元素'''
        l, r = 0, len(nums) - 1
        while l<=r:
            mid = l + (r - l) // 2
            if nums[mid]==target:
                return mid  #注意
            elif nums[mid]<target:
                r=mid+1
            elif nums[mid]>target:
                l=mid-1
        return -1 #注意

    def left_bound(self,nums, target):
        '''寻找左边界'''
        l,r=0,len(nums)-1
        while l<=r:
            mid = l + (r - l) // 2
            if nums[mid]==target:
                r=mid-1 #注意,因为是寻找左边界,所以缩小r,使l最终指向结果
            elif nums[mid]<target:
                l=mid+1
            elif nums[mid]> target:
                r=mid-1

        #检查l的合法性
        if 0>l or l>len(nums)-1 or nums[l]!=target:
            return -1
        else:
            return l #注意

    def right_bound(self,nums, target):
        #寻找右边界
        l,r=0,len(nums)-1
        while l<=r:
            mid = l + (r - l) // 2
            if nums[mid]==target:
                l=mid+1 ##注意,因为是寻找右边界,所以增大l,使r最终指向结果
            elif nums[mid]<target:
                l=mid+1
            elif nums[mid]> target:
                r=mid-1

        #检查r的合法性
        if 0>r or r>len(nums)-1 or nums[r]!=target:
            return -1
        else:
            return r #注意

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值