35. 搜索插入位置

35. 搜索插入位置

题目链接
代码随想录

分析

看提示,升序且无重复元素,要求算法复杂度为 log(n),基本可以确定用二分法。我们看题目中的两个要求

  1. 在数组的两个元素中间,我们用二分法得到的是什么?
    • 首先确定我们要找的是哪个位置?例如数组是 1,3,我们的目标值是 2,那么 3 所在的位置,就是我们要插入 2 的位置,也就是大于目标值的第一个位置
    • 首先我们分析一下当目标元素在数组中的时候,二分法的过程:通过循环,缩短 [start,end] 这个区间,我们可以保证目标严肃一定在 [start,end] 这个区间之内,但是当目标元素不在数组中而是在相邻两个元素(比如 AB,且 A<B )之间的时候,[start,end] 这个区间首先会坍缩成一个点,即 start==end,此时 start 和 end 都处在目标值的一边(任意一边都有可能),此时获取 mid,然后比较 nums[mid] 和目标值,会造成 start > end,最终跳出 while 循环,此时,start 就是我们要找的值。这一段其实比较抽象,我也没想好用什么样的逻辑来讲解。
  2. 目标值小于数组的第一个元素,我们用二分法得到的是什么?
    • start 一直为 0,end 一直减少,直到为 -1,此时 start 的位置就是我们需要返回的位置。
  3. 目标值大于数组的第一个元素,我们用二分法得到的是什么?
    • end 一直为 0,start 一直增加,直到为 nums.length,此时 start 的位置就是我们需要返回的位置。
      可以看到 start 指向的就是大于目标值的第一个位置。这样结果就很简单了。
public int searchInsert(int[] nums, int target) {
    int start =0,end = nums.length-1;
    while(start<=end){
        int mid = start  + (end - start)/2;
        if(nums[mid] == target){
            return mid;
        }else if (nums[mid] < target){
            start = mid +1;
        }else if (nums[mid] > target){
            end = mid - 1;
        }
    }
    // 这里返回 end +1 也是可以的
    // return  end +1;
    return start;
}

解题

这一题实际上考的是使用二分法的时候,如果因为 start>end 退出 while 循环 start 指向的是什么,指向的是大于目标值的第一个位置。
其实我们可以大概推理出 当因为 start>end 退出 while 循环的时候,start=end+1

相关题

704. 二分查找
34. 在排序数组中查找元素的第一个和最后一个位置
69. x 的平方根