Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 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 <=-
<= nums[i] <= nums为 无重复元素 的 升序 排列数组-
<= target <=
思路分析
方法一
遇到此类问题,首先想到的依旧是数组现成的API,使用 findIndex 方法可以找到第一个大于目标值 target 的值,如果返回的是 -1,那么证明整个数组 nums 中没有大于目标值 target 的值,返回数组的长度 nums.length 即可。
方法二
- 算法出现在二分查找的分类下,那么我们可以尝试采用二分查找的方法来完成;
- 还是依旧定义 start 值,以及 end 值,定义结果值 res 为 nums.length;
- 以 start <= end 作为条件来循环,取中值 mid,若中值所在的值大于等于目标值 target 值,那么将 res 记录为当前中值「为了确保左边一半的值都小于目标值」,同时满足条件的一定出现在左边界到中值之间;若中值所在的值小于目标值 target 值,那么满足条件的一定出现在中值到右边界之间。
AC 代码
方法一
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var searchInsert = function(nums, target) {
let index = nums.findIndex(item => item >= target)
if(index === -1) index = nums.length
return index
};
结果:
- 执行结果: 通过
- 执行用时:56 ms, 在所有 JavaScript 提交中击败了91.80%的用户
- 内存消耗:41.2 MB, 在所有 JavaScript 提交中击败了27.33%的用户
- 通过测试用例:64 / 64
方法二
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var searchInsert = function(nums, target) {
let start = 0
let end = nums.length - 1
let res = nums.length
while (start <= end) {
let mid = Math.floor((start + end) / 2);
if (target <= nums[mid]) {
res = mid;
end = mid - 1;
} else {
start = mid + 1;
}
}
return res
};
结果:
- 执行结果: 通过
- 执行用时:60 ms, 在所有 JavaScript 提交中击败了80.27%的用户
- 内存消耗:41.1 MB, 在所有 JavaScript 提交中击败了30.16%的用户
- 通过测试用例:64 / 64