搜索插入位置
难度:
标签:
题目描述
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 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
代码结果
运行时间: 32 ms, 内存: 15.4 MB
// Java Stream Solution
// Problem: Same as above.
// Approach: Use Java Streams to find the index or insertion point. Convert the array to a Stream and use binary search.
import java.util.Arrays;
public class Solution {
public int searchInsert(int[] nums, int target) {
return Arrays.binarySearch(nums, target) >= 0 ? Arrays.binarySearch(nums, target) : -Arrays.binarySearch(nums, target) - 1;
}
}
解释
方法:
这个题解使用了二分查找的思路。首先定义左右边界 l 和 r,分别指向数组的开始和结束位置。然后使用 while 循环进行二分查找,每次循环都计算中点 mid,比较 nums[mid] 和 target 的大小关系。如果 nums[mid] >= target,说明目标值可能在左半部分,将右边界 r 移动到 mid;否则目标值在右半部分,将左边界 l 移动到 mid + 1。最终左右边界重合时,l 即为目标值应该插入的位置。
时间复杂度:
O(log n)
空间复杂度:
O(1)
代码细节讲解
🦆
为什么在比较nums[mid]与target时选择将r移动到mid而不是mid-1,这样的选择对算法的效率和结果有什么影响?
▷🦆
在while循环的条件为l < r而不是l <= r,这样设计的原因是什么?它如何确保不会错过目标值?
▷🦆
如果数组中的元素非常接近或达到了整型的极限值,比如10^4或-10^4,这会对二分查找算法的效果有什么潜在影响?
▷🦆
二分查找的终止条件是l与r重合,即l == r时循环结束。为什么这样的设计能确保找到正确的插入位置?
▷相关问题
第一个错误的版本
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 n
个版本 [1, 2, ..., n]
,你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用 bool isBadVersion(version)
接口来判断版本号 version
是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
示例 1:
输入:n = 5, bad = 4 输出:4 解释:调用 isBadVersion(3) -> false 调用 isBadVersion(5) -> true 调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。
示例 2:
输入:n = 1, bad = 1 输出:1
提示:
1 <= bad <= n <= 231 - 1