搜索插入位置
发布日期:2021-05-12 05:49:57 浏览次数:13 分类:精选文章

本文共 2160 字,大约阅读时间需要 7 分钟。

在这篇文章中,我们讨论了如何在已排序的数组中找到目标值的位置。我们将使用二分查找算法来实现这一目标,这种算法在已排序数组中搜索的效率远高于线性搜索。通过中间点条件,我们可以有效地缩小搜索范围,快速定位目标值或者确定插入位置。

二分查找方法

二分查找算法的基本步骤可以总结如下:

  • 初始化指针:设置数组的两个指针,begin 从数组起点 (0 )开始,end 从数组终点 (nums.length - 1) 开始。

  • 进入循环:当 begin 小于等于 end 时,继续执行循环。

  • 计算中间点:在当前 beginend 区间中,计算中间点 mid

  • 比较目标值与中间值

    • 如果目标值小于中间值,说明目标值位于中间值的左边,于是将 end 更新为 mid - 1
    • 如果目标值大于中间值,说明目标值位于中间值的右边,于是将 begin 更新为 mid + 1
    • 如果目标值等于中间值,直接返回中间点的索引 mid
  • 确定插入位置:如果整个循环结束后仍未找到目标值,说明目标值不存在于数组中。此时,需要返回目标值在已排序数组中应该插入的位置。这个位置将是 begin 的当前值,因为它已经超过了所有已知元素的右侧。

  • 代码实现

    通过上述逻辑,我们可以编写如下的Java代码:

    public class Solution {    public int searchInsert(int[] nums, int target) {        int begin = 0;        int end = nums.length - 1;        while (begin <= end) {            int mid = (begin + end) / 2;            if (target < nums[mid]) {                end = mid - 1;            } else if (target > nums[mid]) {                begin = mid + 1;            } else {                return mid;            }        }        return begin;    }}

    测试示例

    让我们通过一些测试用例来验证该算法的正确性。

    示例1:数组:[1,3,5,6]目标值:5

    期望输出:2
    代码分析:

    • 初始,begin=0end=3
    • mid = (0 + 3) / 2 = 1nums[1]=3。因为5 > 3,begin 被设定为2。
    • 接下来的循环中,mid=(2 + 3)/2 = 2nums[2]=5,与目标值相等,返回2。

    示例2:数组:[1,3,5,6]目标值:2

    期望输出:1
    代码分析:

    • mid=1nums[1]=3 > 2,所以将 end 设定为1-1=0。
    • 接下来的循环中,mid=0nums[0]=1 < 2,所以将 end 设定为-1。循环结束后,返回 begin=1

    示例3:数组:[1,3,5,6]目标值:7

    期望输出:4
    代码分析:

    • mid=1nums[1]=3 <7,begin 设为2。
    • mid= (2+3)/2=2nums[2]=5 <7,begin 设为3.
    • mid=3nums[3]=6 <7,所以 begin 被设定为4。
    • begin >= end 时,返回4。

    示例4:数组:[1,3,5,6]目标值:0

    期望输出:0
    代码分析:

    • mid=1nums[1]=3 >0,所以 begin 被设定为1,进入下一个循环。
    • mid=(1+3)/2=2nums[2]=5 >0,继续将 begin 设定为3.
    • mid=3nums[3]=6 >0,begin 设定为4。
    • 循环结束,返回 begin=4 的值,哦,不对,这里期望的是返回0。这可能是一个测试案例中特殊情况的处理吗?让我重新审视一下。

    哦哦,原来如此,如果目标值比所有元素都小,那么循环结束时,begin 会被设定为数组的长度,就是4,那么返回4。这刚好符合插入位置是在前面所有元素之后的位置。但是对于示例4,输入是0,期望的输出是0,因为应该插入在第一个位置的前面。

    那这个时候,我是不是哪里弄错了?看来原始代码可能需要再仔细检查一下。

    再仔细思考示例4的情况:

    输入数组是1,3,5,6,查找0,那么在所有元素前面。所以插入的位置应该是0。按照现有代码运行,什么时候会这样:

    初始begin=0,end=3。先算mid=1,nums[1]=3,0<3,end=0.

    接下来mid=0,nums[0]=1,0<1,end=-1,退出循环。return begin=0。这与期望结果一致。

    哦,我的测试可能在更详细地思考中弄错了。那我再验证一下代码是否正确:

    确实,示例4中的0比所有元素都小,所以每次都会进入 target < nums[mid] 的情况,直到 end=-1,返回begin=0。这样,代码是正确的。可能我在刚才的分析中错误地修改了代码,但实际上代码是正确的。

    所以,以上代码在所有示例中都能正确工作。

    上一篇:[leetcode-数组]旋转矩阵
    下一篇:高内聚低耦合

    发表评论

    最新留言

    路过,博主的博客真漂亮。。
    [***.116.15.85]2025年04月23日 17时51分45秒