力扣35题搜索插入位置Q35SearchInsertPosition

Q35SearchInsertPosition

题目描述

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

请必须使用时间复杂度为 O(log n) 的算法。

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

https://leetcode.cn/problems/search-insert-position


解题思路

首先考虑暴力解法,但暴力的时间复杂度是 O(n) 不符合题目要求,像这种找目标值的首先考虑二分法。二分法要注意的就是 left < right 还是left <= right 的选择问题和区间缩小时的定界。

解题如下
首先初始化为left=0,right=len,因为数组长度位置即最后一个元素后面的位置也可为答案。最初的搜索区间为[0, len],也就是left ~ right,在搜索过程中有如下情况

  • 当中间值小于目标值时,mid和mid往左的位置都不是所要找的位置,left应等于mid+1,搜索区间变为[mid+1, right]
  • 其余情况,中间值大于等于目标值,那么mid的位置可能是要找的位置,但mid往右绝对不是要找的位置,故right变为mid,搜索区间变为[left, mid]
  • 搜索终止时,一定有left==right,也就是区间[left, right]里面一定有要找的位置,此时返回left或right任一即可。

代码

public class Q35SearchInsertPosition {
    public int searchInsert(int[] nums, int target) {
        if(null == nums || nums.length == 0){
            return 0;
        }
        int left = 0;
        int right = nums.length;
        while(left < right){
            int mid = left + (right - left) / 2;
            if (nums[mid] < target){
                left = mid + 1;  //缩小区间为[mid+1, right]
            } else {
                right = mid;     //缩小区间为[left, mid]
            }
        }
        return left;
    }
}

本地测试

public class Q35SearchInsertPositionTest {
    private static final Q35SearchInsertPosition q = new Q35SearchInsertPosition();

    @Test
    public void test1(){
        assertEquals(2, q.searchInsert(new int[]{1,3,5,6}, 5));
    }

    @Test
    public void test2(){
        assertEquals(1, q.searchInsert(new int[]{1,3,5,6}, 2));
    }

    @Test
    public void test3(){
        assertEquals(4, q.searchInsert(new int[]{1,3,5,6}, 7));
    }

    @Test
    public void test4(){
        assertEquals(0, q.searchInsert(new int[]{1,3,5,6}, 0));
    }

    @Test
    public void test5(){
        assertEquals(0, q.searchInsert(new int[]{1}, 0));
    }

}

提交

图 1

posted @ 2022-08-10 22:59  Mr耀  阅读(66)  评论(0)    收藏  举报