二分查找思路

文章介绍了二分查找算法的基础概念,包括在有序数组中查找或插入元素的思路,以及如何通过不断舍弃不符合条件的区间来达到O(logn)的时间复杂度。讨论了二分法编写时的主要问题,如left和right的变化以及退出条件的选择,并给出了具体的Java代码实现。
摘要由CSDN通过智能技术生成

算法刷题-基础篇

二分查找/插入

1.基本思路

二分查找主要运用于有序数组(至少要有一定规律),通过每次舍去区间中不满足要求的一部分从而达到O(logn)的时间复杂度

2.例子

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。(你可以认为数组严格递增)

请必须使用时间复杂度为 O(log n) 的算法。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/search-insert-position

3.分析

二分法就是去除数据中不符合要求的一半,从而达到时间复杂度为 O(log n) 的目的,因而一般二分是针对有序数据设置left和right两个边界点,并以mid=(left+rigth)/2此作为是否舍弃的依据,属于思路简单但是编写多变的算法。

实际上,二分法问题在编写的时候面临的主要问题有两个:

1、mid不符合条件之后,left和right如何变化?
答:在代码中一般以0作为初始的left,而right依据实际情况而定,由于在代码中float转int是直接截断,这就导致问题转化为mid是否需要保留,由mid 的计算方式可以得出一定条件下mid会等于left(left+1==right)。因而为了保障程序不会死循环,一般是left=mid+1或者right=mid-1,另一半保持不变作为下一次循环的初始条件。
简而言之,当mid不符合条件,你需要舍弃哪一部分的数据。

2、中止条件是left>right还是left>=right?
这个主要是查看当left与right的时候是否需要继续,一般与你的二分查找的返回值有关。需要注意的是当left>right作为退出的时候left最多等于right,
left>=right时left最多等于right+1

4.实际编写

首先要针对具体问题具体分析,此题要求的是找到严格小于target的最后一个数字,最后返回其索引加一。我们需要明确的有下列条件
a.数组严格递增
b.需要的是最后一个小于target的数据的索引+1

为了不失一般性,选择mid作为返回值。我们不妨以left>right作为退出条件,思考极限情况,则循环退出时left=right但是mid不等于他们两个,故最终返回值如下

 return left==right?left: mid;

此时二分法的思路就很明确了,当nums【mid】=target 直接break即可

当nums【mid】<target时我们需要舍弃掉【left,mid】这一部分的数据。这很好理解,我们需要mid往上增加作为最终的返回值,思考极限情况
【1,3】作为nums,2作为target,初始left=0,right=1,则mid=0,而我们所需要的结果为1,因而需要left=mid+1作为此时跳转条件

if(nums[mid]<target)
        {
            left=mid+1;
        }

同理,当nums【mid】>target,我们需要舍弃【mid+1,right】这一部分数据,因而需要令right=mid

   else  if(nums[mid]>target)
            {
                right=mid;
            }

最后,我们可以通过令right=nums.length来避免进行一次额外判定,最后完整java代码如下:

class Solution {
    public int searchInsert(int[] nums, int target) {
        int left=0;
        int right=nums.length;
        int mid=0;
        while(left<right)
        {
            mid=(left+right)/2;
          
            if(nums[mid]<target)
            {
                left=mid+1;
            }
            else  if(nums[mid]>target)
            {
                right=mid;
            }
            else
            {
                break;
            }
        }
        return left==right?left: mid;
    }
}

复杂度分析:

时间复杂度:O(log⁡N),这里 N是输入数组的长度;
空间复杂度:O(1)。

5.拓展

最后,不妨思考如果退出条件为left<=right的时候相应的思考过程是怎么样的?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值