本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
输入: nums = [1,3,5,6], target = 5
输出: 2
题目解析
思路一
升序数组,如果target小于某个值,那么target就要插入这个位置。遍历到最后target还是最大的,那么target就应该放在最后。如果遍历中等于某个值,那么就返回下标。否则直接return结束for所在的函数
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var searchInsert = function(nums, target) {
for(i=0;i<nums.length;i++){
if(target <= nums[i])
{
return i;
};
}
return nums.length;
}
思路二
我们可以通过数组的indexOf 方法判断目标值是否在数组nums中,若是则直接返回其下标,在定义变量
i = 0,通过for循环遍历nums数组,判断每个元素,若该元素小于目标值,将其赋值给i,循环完成,返回i
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var searchInsert = function(nums, target) {
if(nums.indexOf(target) >=0){
return nums.indexOf(target)
}
let i = 0
for(let a = 0;a<nums.length;a++){
if(nums[a] < target){
i = a+1
}
}
return i
};
思路三
这里采用二分实现
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var searchInsert = function(nums, target) {
var left = 0 ;
var right = nums.length - 1;
// 最前
if(target <= nums[0]){
return 0
}
// 最后
if(target > nums[nums.length-1]){
return nums.length;
}
while(left <= right){ //[left,right]区间内取值
var mid = Math.floor((left + right)/2);
if(target < nums[mid]){ //比中间小,落在左区间 [left, mid-1]
right = mid - 1;
}else if(target > nums[mid]){ //比中间大,落在右区间 [mid+1, right]
left= mid + 1;
}else{//相等
return mid;
}
}
// 如果left==right, target>nums[left],那么left = left +1 ,这是是正好要插入的位置,target有可能< nums[left] ,这个时候left,right都是可选的
return left ; //这时候的left ==right+1;
};