搜索插入位置 - LeetCode 热题 63

大家好!我是曾续缘❣️

今天是《LeetCode 热题 100》系列

发车第 63 天

二分查找第 1 题

❤️点赞 👍 收藏 ⭐再看,养成习惯

搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

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

示例 1:

输入: nums = [1,3,5,6], target = 5
输出: 2

示例 2:

输入: nums = [1,3,5,6], target = 2
输出: 1

示例 3:

输入: nums = [1,3,5,6], target = 7
输出: 4

提示:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums 为 无重复元素 的 升序 排列数组
  • -104 <= target <= 104
难度:❤️

解题方法

题目要求我们在一个已经排序的数组中找到目标值,并返回它的索引。如果目标值不在数组中,我们需要返回它应该插入的位置。为了达到题目要求的时间复杂度$ O(log n)$,我们使用二分查找算法来解决这个问题。

二分查找是一种高效的查找算法,它每次将查找区间减半,适用于有序数组。算法的基本思想是:

  1. 初始化两个指针l(左指针)和r(右指针),分别指向数组的起始和结束位置。左指针表示可能的插入位置的下界,右指针表示上界。
  2. 计算中间位置:在每次循环中,计算lr的中间位置mid,即(l + r) / 2。将中间位置的元素与目标值进行比较。
  3. 比较中间元素与目标值
    • 如果中间元素nums[mid]等于目标值target,则直接返回mid,因为找到了目标值。
    • 如果nums[mid]大于target,说明目标值应该在左半部分,我们将右指针r移动到mid - 1的位置。
    • 如果nums[mid]小于target,说明目标值应该在右半部分,我们将左指针l移动到mid + 1的位置。
  4. 重复上述过程:继续在更新后的区间内进行二分查找,直到找到目标值或者l大于r
  5. 返回结果
    • 如果在数组中找到了目标值,算法会在找到目标值时立即返回其索引。
    • 如果目标值不在数组中,当l大于r时循环结束,此时l指向的就是目标值应该插入的位置。

我们使用的是左闭右闭 [l, r] 的区间方式。这种方式在处理边界值时比较直观,因为不需要担心数组越界的问题。当 lr 相等时,区间中仍然包含一个元素,这也是为什么循环条件是 l <= r 的原因。当 nums[mid] 不等于 target 时,更新指针时,l 会设置为 mid + 1r 会设置为 mid - 1,因为中间值 mid 已经被检查过了,不需要再次检查。

在二分查找算法中,区间的开闭指的是在每一步迭代中,是否包含区间的边界值。具体来说,区间可以是左闭右闭 [l, r]、左闭右开 [l, r)、左开右闭 (l, r] 或者左开右开 (l, r)。在实现二分查找时,选择哪种区间开闭方式会影响循环条件和指针更新的方式。

左闭右闭 [l, r]

  • 初始条件:l = 0, r = n - 1
  • 循环条件:l <= r
  • 左指针更新:l = mid + 1
  • 右指针更新:r = mid - 1

左闭右开 [l, r)

  • 初始条件:l = 0, r = n
  • 循环条件:l < r
  • 左指针更新:l = mid + 1
  • 右指针更新:r = mid

左开右闭 (l, r]

  • 初始条件:l = -1, r = n - 1
  • 循环条件:l < r
  • 左指针更新:l = mid
  • 右指针更新:r = mid - 1

左开右开 (l, r)

  • 初始条件:l = -1, r = n
  • 循环条件:l + 1 < r
  • 左指针更新:l = mid
  • 右指针更新:r = mid

Code

class Solution {
    public int searchInsert(int[] nums, int target) {
        int n = nums.length;
        int l = 0, r = n - 1;
        while(l <= r){
            int mid = (l + r) / 2;
            if(nums[mid] == target){
                return mid;
            }else if(nums[mid] > target){
                r = mid - 1;
            }else{
                l = mid + 1;
            }
        }
        return l;
    }
}
  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值