Go&Java算法之搜索插入位置

120 阅读1分钟

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

搜索插入位置

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

请必须使用时间复杂度为 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

示例 4:

输入: nums = [1,3,5,6], target = 0

输出: 0

示例 5:

输入: nums = [1], target = 0

输出: 0  

提示:

1 <= nums.length <= 104

-104 <= nums[i] <= 104

nums 为无重复元素的升序排列数组

-104 <= target <= 104

题解

算法一:二分查找(Java)

  • 这道题目,要在数组中插入目标值,无非是这四种情况。
    • 目标值在数组所有元素之前
    • 目标值等于数组中某一个元素
    • 目标值插入数组中的位置
    • 目标值在数组所有元素之后

二分查找涉及的很多的边界条件,逻辑比较简单,就是写不好 —— 二分查找法中边界条件处理不好。

例如到底是 while(left < right) 还是 while(left <= right),到底是right = middle呢,还是要right = middle - 1呢?

要在二分查找的过程中,保持不变量,这也就是循环不变量。

class Solution {
    public int searchInsert(int[] nums, int target) {
        if (nums == null || nums.length == 0) {
            return -1;
        }

        int mid;
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] > target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return right + 1;
    }
}

时间复杂度:O(logN)

空间复杂度:O(1)

算法一:二分查找(Go)

func searchInsert(nums []int, target int) int {
	if len(nums) == 0 || target <= nums[0] {
		return 0
	}

	if target > nums[len(nums) - 1] {
		return len(nums)
	}

	left, right := 0, len(nums) - 1
	for right - left > 1 {
		mid := (left + right + 1)/2
		if nums[mid] >= target {
			right = mid
		}
		if nums[mid] <= target {
			left = mid
		}
	}
	return right
}

时间复杂度:O(logN)

空间复杂度:O(1)