Java描述 LeetCode,35. Search Insert Position搜索插入位置

本文介绍了如何使用二分查找算法在已排序的整数数组中找到目标值的索引,或者确定其应插入的位置。讨论了算法的逻辑、代码实现以及特殊情况的处理,强调了在边界条件下的正确处理。提供的代码示例展示了如何在O(logn)的时间复杂度内完成搜索插入位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家好,我是河海哥,专注于后端,如果可以的话,想做一名code designer而不是普通的coder,一起见证河海哥的成长,您的评论与赞是我的最大动力,如有错误还请不吝赐教,万分感谢。一起支持原创吧!

1-1:题目

Given a sorted array of distinct integers and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

You must write an algorithm with O(log n) runtime complexity.

Example 1:

Input: nums = [1,3,5,6], target = 5
Output: 2

Example 2:

Input: nums = [1,3,5,6], target = 2
Output: 1

Example 3:

Input: nums = [1,3,5,6], target = 7
Output: 4

Example 4:

Input: nums = [1,3,5,6], target = 0
Output: 0

Example 5:

Input: nums = [1], target = 0
Output: 0

Constraints:

1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums contains distinct values sorted in ascending order.
-104 <= target <= 104

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

1-2:idea

在有序的数组中查找目标位置,logn很容易就想到,用二分查找,这里还有额外一个条件,如果说没有找到这个数字,就返回他该插入的地方,通过example可以看出,如果说,没有找到这个数,其实返回的位置就是数组第一个比target大的数的位置。整个代码的核心就在于,画个图:
在这里插入图片描述
试想如果是这种情况nums[mid] < target,你该怎么办?该往右去逼近target,每次碰到这个条件的时候,mid就会往target处逼近一点,但是target永远大于nums[mid],所以只会得到比target小的那些数里面最大的那个数。所以这不是我们想要的,想要的是下面这种情况。
在这里插入图片描述
这种情况之下,就懂了呀,无限向左边逼近,那么要么得到target要么得到,第一个比target大的数字。

1-3:代码

public static int searchInsert2(int[] nums, int target) {
    int n = nums.length;
    int pos = n; // 边界的技巧
    int left = 0;
    int right = n - 1;
    while (left <= right) {
        int mid = (left + right) >> 1;
        if (nums[mid] < target) {
            left = mid + 1;
        } else {
            pos = mid;
            right = mid - 1;
        }
    }
    return pos;
}

上面的代码可以完美解决边界问题,比如target<nums[0]的时候,最后的值刚好就是0。另外pos初值就是n,如果是[1,2,3,4] 插5,pos还是n不会随着遍历而改变。那么这个代码找的就是第一个>=target的位置。

2022-2-2更:
另外一种写法

public int searchInsert3(int[] nums, int target) {
    int n = nums.length;
    if (target > nums[n - 1]) {
        return n;
    }
    if (target < nums[0]) {
        return 0;
    } // 这两个判断可以直接筛掉边界的情况
    int left = 0;
    int right = n - 1;
    while (left <= right) {
        int mid = left + ((right - left) >> 1);
        if (nums[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    // 最后left指的位置就是需要插入的位置了
    return left;
}

1-4:总结

通过两张图可以完美理解了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

河海哥yyds

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值