算法练习第2道-查找学习

254 阅读1分钟

这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

分析

得到题目,我们来分析

  • 首先是有两种情况,一种是在数组中,一种是不在数组中
  • 在数组中,我们直接返回目标下标
  • 不在数组又有两种情况,一种是在数组区间内,一种不在数组区间内
  • 不在数组区间又分小于数组最小值和大于数组最大值

逻辑处理

第一种情况: 判断在不在数组中,在数组中返回下标

if(nums.indexOf(target) < 0) {
   // ....
} else {
   return nums.indexOf(target)
}

处理不在数组中的情况,最大值和最小值

对比数组的第一个值,如果它小于最小值,那么就直接返回0, 如果不是判断是否大于最大值,如果是,就返回length

if(nums[0]> target) {
   return 0
} else if ((nums[nums.length -1]< target)) {
   return nums.length
} 

之后处理在数组中的值

for循环内处理,比对target,如果对比的值大于target就返回当前下标

for(let i = 0; i < nums.length; i++) {
   if(nums[i]>target) {
     return i
  }
}

完整代码

以上就是所有的处理逻辑,下面是完整的代码

let searchInset = function(nums, target) {
  if(nums.indexOf(target) < 0) {
    if(nums[0]> target) {
      return 0
    } else if ((nums[nums.length -1]< target)) {
      return nums.length
    } else {
      for(let i = 0; i < nums.length; i++) {
        if(nums[i]>target) {
          return i
        }
      }
    }
  } else {
    return nums.indexOf(target)
  }
}

优化问题

现在看上边的if判断,不在区间内处理的时候,target小于最小值的情况包含在了for循环中,因此代码应该如下

 if(nums.indexOf(target) < 0) {
    if ((nums[nums.length -1]< target)) {
      return nums.length
    } else {
      for(let i = 0; i < nums.length; i++) {
        if(nums[i]>target) {
          return i
        }
      }
    }
  } else {
    return nums.indexOf(target)
  }

然后在思考下,发现我们其实还可以在改改,比如在取值的时候,nums[0]总是要比nums[nums.length -1]好的,然后我们合并下这个target存在数组的情况

修改后如下

if(nums[0]> target) {
    return 0
}
let len = nums.length
for(let i = 0; i < len; i++) {
    if(nums[i] >= target) {
      return i
    }
}
return nums.length

未完待续....