问题描述
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 1:
输入: [1,3,5,6], 5
输出: 2
示例 2:
输入: [1,3,5,6], 2
输出: 1
示例 3:
输入: [1,3,5,6], 7
输出: 4
示例 4:
输入: [1,3,5,6], 0
输出: 0
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-insert-position
Related Topics 数组 二分查找
解法
解法一
class Solution {
public int searchInsert(int[] nums, int target) {
// 暴力解法,从头开始遍历
/* 无非就四种情况
1、目标值在数组所有元素之前
2、目标值等于数组中某一个元素
3、目标值不等于数组中某一个元素,需要插入数组中的位置
4、目标值在数组所有元素之后
*/
//前三种情况,一旦发现大于或者等于target的num[i],那么i就是我们要的结果
for(int i = 0; i < nums.length; i++) {
if (nums[i] >= target) {
return i;
}
}
//目标值在数组所有元素之后的情况
return nums.length;
}
}
暴力解法时间复杂度:O(n)
解法二
考虑到这是一个有序且无重复元素的数组,可以考虑使用二分法
class Solution {
public int searchInsert(int[] nums, int target) {
//二分法
int left = 0;
int right = nums.length - 1; //定义target在左闭右闭的空间里,[left, right]
while (left <= right) { //当left == right,区间[left, right]依然有效
int middle = left + (right - left) / 2; //防止溢出,等同于(left + right)/2
if (nums[middle] > target) {
right = middle - 1;
}
else if (nums[middle] < target) {
left = middle + 1;
}
else {
return middle;
}
}
// 分别处理如下四种情况 可以以这个数组为例思考一下 2 3 8 9 11
// 目标值在数组所有元素之前 [left, right]最终会变成[0, -1],此时right = -1,要返回0,就是right + 1
// 目标值等于数组中某一个元素 return middle;
// 目标值插入数组中的位置 [left, right], return right + 1
// 目标值在数组所有元素之后的情况 [left, right], return right + 1
return right + 1;
}
}
二分法时间复杂度:O(logn)