搜索插入位置

77 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第38天,点击查看活动详情

题目描述

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
来源:力扣(LeetCode)

  • 示例 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

思路分析

根据题意可知,题目给出一个排序数组nums和一个目标值target。需要在数组中找到目标值,并且返回索引。如果目标值没有在数组里面,就返回它将会被按顺序插入的位置。并且需要使用时间复杂度为 O(log n) 的算法。
这里有许多可能性,如果数组nums中的元素都比target小,那么target就是需要插入到数组的最后面;反之,如果数组nums中的元素都比target大,那么target就需要插入到数组的最前面。
如果数组中间的数值等于target,那么就直接返回数组中间的下标。
如果数组中的数值大于target,就需要往左边的元素区间[left, mid]之间取中间值做比较;如果刚好这样取到的中间值等于target,那就可以直接将此时的中间值的下标返回出去,如果不相等,就继续上面的操作继续做左边的中间值做比较。如果取到左边的值比target值小,右边的值比target大,两个值又相邻,那么就将值插在中间

AC代码

function solution(nums, target) {
   let left = 0;
   let right = nums.length-1;
   let mid = Math.floor(nums.length/2);
   if(nums[right] < target) {
       return nums.length;
   }
   if(nums[left] > target) {
       return 0;
   }
   while(true) {
       if(nums[mid] === target) {
           return mid;
       }else if(nums[mid] < target) {
           left = mid;
           mid = left + Math.floor((right- left)/2)
       }else{
           right = mid;
           mid = left + Math.floor((right-left)/2)
       }
       if(nums[left] === target) {
           return left;
       }
       if(nums[right] === target) {
           return right;
       }
       if(nums[left] != target && nums[right] != target && right-left == 1) {
           return left+1;
       }
   }
}
let nums = [1,3,5,6], target = 4;
solution(nums, target);