[LeetCode][面试算法]逻辑闭环的二分查找代码思路

✌️作者清水寺丞
☀️简介:正在学习算法,unity,数据库,计算机通信网络和python。喜欢部署各种奇奇怪怪的小项目。喜欢就点个关注一起学习吧~⛄️⛄️⛄️⛄️

目录

一、前言

二、二分查找

核心思想简述:

三、代码示范1

注释版:

纯净版代码:

四、代码示范2 (left<=right):


一、前言

        作者在学习二分查找时,常常遇到对于二分查找的思想一学就会,真正写起来却困难重重的问题。每一次在写二分查找的代码时,常常弄不清是while(left<right)还是while(left<=right),也常常弄不清楚是left=mid+1还是left=mid。

        于是写下这篇文章,来理清二分思想的思路,从思路上理解是while(left<right)还是while(left<=right);是left=mid+1还是left=mid。

二、二分查找

核心思想简述:

我们在算法运行过程中,每次更新中保证target的下标一定属于一个范围,然后我们不断缩小这个范围,当这个范围小到没有任何数在其中时,数组中没有这个数。

由于我们每次缩小范围都保证target的下标一定属于这个范围,故若数组中有这个数,在这个可能范围缩小到0的过程中,我们一定会发现target在这个范围的中央。

三、代码写法1

题目来自Leetcode

704. 二分查找

我们将在代码的思路简析与注释中了解如何具体确定target可能出现的下标范围。

代码思路简析:我们在算法运行过程中,每次更新中保证target的下标一定属于[left,right),然后我们不断缩小[left,right)这个范围

当left=right或left<right,则范围[left,right)中不存在任何数,而我们在更新中保证了target一定处于[left,right)这个范围中,当[left,right)中不可能存在数时,target一定不存在于数组中。

注释版:

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        n=len(nums)
        #我们定义target可能的下标范围为[left,right)
        #在算法中缩小范围时我们也要保证每一次更新后,
        #target可能出现的下标范围仍然为[left,right)
        #我们通过不断地缩小target可能出现的范围来找到target
        #若target可能出现的下标范围已经小到没有数在其中
        #则target不存在数组中

        #一开始,target的下标可能存在范围为[0,n)
        left=0
        right=n
        
        #因为target可能出现的下标范围为[left,right)
        #故当left=right时,target已经不可能出现了
        while(left<right):
            #当前搜索范围的中心下标为int((left+right)/2)
            mid=int((left+right)/2)
            if(nums[mid]>target):
                #如果中心的数大于target,由于升序,target的下标可能范围为[left,mid)
                #故为了保证target属于[left,right),right=mid
                right=mid
            elif(nums[mid]<target):
                #如果中心的数小于target,由于升序,target的下标可能范围为(mid,right)
                #故为了保证target属于[left,right),left=mid+1
                left=mid+1
            else:
                #若中心的数就是target,则返回中心下标
                return mid
        
        #当left<right
        #target可能下标范围[left,right)缩小到其中没有一个数
        return -1

纯净版代码:

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        n=len(nums)
        left=0
        right=n
        while(left<right):
            mid=int((left+right)/2)
            if(nums[mid]>target):
                right=mid
            elif(nums[mid]<target):
                left=mid+1
            else:
                return mid
        
        return -1

四、代码写法2 (left<=right):

这次我们保证target一定在[left,right]的范围内。

大家可以根据之前的逻辑自行练习。

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        n=len(nums)
        #target下标在[left,right]
        left=0
        right=n-1
        #因为在[left,right]内,所以left=right时范围内仍然有下标存在
        while(left<=right):
            mid=int((left+right)/2)
            if(nums[mid]<target):
                #target属于(mid,right]
                left=mid+1
            elif(nums[mid]>target):
                #target属于[left,mid)
                right=mid-1
            else:
                return mid
        
        return -1

猜你喜欢

转载自blog.csdn.net/m0_56738500/article/details/127186931
今日推荐