前端算法(33)

82 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

题目

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 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;
};