力扣704. 二分查找边界问题

只讲几个边界的注意点

问题:

看下面这这两段代码

        左闭右闭
   
        int left = 0;
        int right = nums.length - 1;


        while (left <= right){
       
            //找到了返回
            if(nums[middle] < target){
                left=middle+1;
            }else if(nums[middle] > target){
                right = middle -1;
            }
    
        左闭右开
   
        int left = 0;
        int right = nums.length;


        while (left <= right){
       
            //找到了返回
            if(nums[middle] < target){
                left=middle+1;
            }else if(nums[middle] > target){
                right = middle;
            }



解释:

1.什么叫左闭右闭?左闭右开?

  • 左闭 :表示左边的边界是包含在内的 ,也就是说,left 这个位置是可以被考虑的。
  • 右开 :表示右边的边界是不包含在内的 ,也就是说,right 这个位置是不能被考虑的

  eg.

  [-1,0,3,5,9,12] 

   左:搜索范围是-1到12。

   左:搜索范围是-1到9,12不在考虑范围 。

2.代码解释

        左闭右闭
   
        int left = 0;
        int right = nums.length - 1;
        
        /*
        为什么这里是 left <= right
        因为你的搜索范围是 [0~nums.length - 1],
        也就说我每一个值都要考虑,
        如果是 < 且  搜索范围是 [0~nums.length - 1],
        那么一定就会搜索范围就会比[0~nums.length - 1]小,
        因为 left < right,就会少left=rigth的值。
           
        */
        while (left <= right){
       
            //找到了返回
            if(nums[middle] < target){
                /*
                这里为什么是 left = middle+1 而不是 left=middle;
                因为,你的搜索范围是[0~nums.length - 1]也就说数组每一个值都可以取到
                而你 nums[middle] < target条件成立,也就意味着你此时nums[middle]一定不等于target
                所以只需要left=middle+1 进行下一个值
                right = middle -1同理

                */
                left=middle+1;
            }else if(nums[middle] > target){
                right = middle -1;
            }
    
        左闭右开
   
        int left = 0;
        int right = nums.length;
          /*
        为什么这里是 left < right,
        因为你的搜索范围是 [0~nums.length],
        eg.[-1,0,3,5,9,12]
        length=6
        nums[5]=12;
        所以,会取到12后面还有一个值,但是取不到这个值,会报索引异常。
           
        所以,这里要求是left<right 也就说right这个位置不可以取到,
        取到会报索引异常。
   
        */

        while (left < right){
       
            //找到了返回
            if(nums[middle] < target){

                /*
                为什么这里是 left=middle+1;而不 left=middle;
                因为这里搜索范围是左闭右开,
                也就意味着你左边的值,nums[middle] < target 这个判断成立时,
                nums[middle]一定不等于target,
                进行+1找下一个值即可。

                */
                left=middle+1;
            }else if(nums[middle] > target){
                /*
                为什么这里是 right = middle;而不是 right = middle+1;
                因为这里搜索范围是左闭右开,意味着
                nums[middle] > target 这个成立时,
                target一定在middle左边的区域,
                而我们的搜索范围是[left,right),取不到right
                所以可以直接right = middle;

                [left,right) == [left,right-1]
                */
                right = middle;
            }



  总结

1.搞清楚到底用哪个边界,是左闭右闭,还是左闭右开。

2.确定好边界范围,只要思考我的搜索范围能不能这个值,就可以写对。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值