持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情
题目
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 示例 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
解决方法
第一种(while)
思路:首先通过while,分界定于数组的值小于目标值,满足需求题目
var searchInsert = function(nums, target) {
let i =0;
while(i<nums.length && nums[i]<target){
i++
}
return i;
};
第二种(二分查找)
思路:假设题意是叫你在排序数组中寻找是否存在一个目标值,那么训练有素的读者肯定立马就能想到利用二分法在 O(\log n)O(logn) 的时间内找到是否存在目标值。但这题还多了个额外的条件,即如果不存在数组中的时候需要返回按顺序插入的位置,那我们还能用二分法么?答案是可以的,我们只需要稍作修改即可。
问题转化到这里,直接套用二分法即可,即不断用二分法逼近查找第一个大于等于 target 的下标 。下文给出的代码是笔者习惯的二分写法,ans 初值设置为数组长度可以省略边界条件的判断,因为存在一种情况是target 大于数组中的所有数,此时需要插入到数组长度的位置。
var searchInsert = function(nums, target) {
for(let i =0;i<nums.length;i++){
if(target<=nums[i]){
return i;
}
}
return nums.length;
};
第三种(位运算)
var searchInsert = function(nums, target) {
const length = nums.length;
if (nums[length - 1] < target) {
return length;
} else if (length === 0) {
return 0;
}
let left = 0;
right = length - 1;
while (left < right) {
let mid = (left + right) >>> 1;
if (target > nums[mid]) {
left = mid + 1;
} else {
right = mid;
}
}
return right;
};