这是我参与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)