1、题意描述
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 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
2、解题思路
其实对于这个题呢,我们可以用遍历整个数组的方法来求解,也就最简单的方式,但是,这种方法的话,我们的时间复杂度为O(n),但是题目要求的时间复杂度为O(log n),所以就不能用这种直接遍历的方式去解题。
分析我们日常的搜索算法,我们很容易就可以想到二分查找法的时间复杂度就是O(log n),所以我们就可以用二分查找的方式来解决这个问题。
3、代码示例
public class L35_SearchInsert {
public static void main(String[] args) {
L35_SearchInsert searchInsert = new L35_SearchInsert();
int[] nums = {1,3,5,6};
searchInsert.searchInsert(nums, 2);
}
public int searchInsert(int[] nums, int target) {
// 查看目标值是否小于数组第一个元素或者大于数组最后一个元素
if(target < nums[0]){
return 0;
}
if(target > nums[nums.length - 1]){
return nums.length;
}
// 使用二分查找法去找元素
int left = 0;
int right = nums.length - 1;
int mid = 0;
int index = 0;
while(left < right){
/**
* 注意下面将mid的值赋给left或者right的时候
* 必须要有一个+1或者一个-1
* 否则会出现死循环
*/
mid = (left + right) / 2;
// 中间的右边符合情况
// (如果是传统二分法的话)但是mid这个已经比较过了,我需要往后移动一个
if(nums[mid] < target){
left = mid + 1;
index = mid + 1;
}
// 中间的左边符合情况
// (如果是传统二分法的话)但是mid这个已经比较过了,我需要往前移动一个
else if(nums[mid] > target){
right = mid;
index = mid;
}
else{
return mid;
}
}
// 返回最后一次计算的mid,如果是左(+1),如果是右,直接拿
return index;
}
}