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
示例 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
2.答题
思路1(二分查找):
- 高低位两个指针high、low,取中间值middle,
- 若middle指向的值等于目标值,直接返回middle
- 若middle指向的值高于目标值,高位指针置为middle-1,
- 若middle指向的值高于目标值,低位指针置为low+1,
public int searchInsert(int[] nums, int target) {
int low = 0;
int high = nums.length - 1;
while (low <= high) {
int middle = (high + low) / 2;
if (nums[middle] == target) {
return middle;
}
if (nums[middle] > target) {
high = middle - 1;
} else {
low = middle + 1;
}
}
return low;
}
时间复杂度
可根据二分查找的时间复杂度计算,若数组长度定位n,每次二分查找,查找区间变为原来的1/2,具体变化如下:
当区间的值等于1时,必定会结束循环,也就是2^k = n,k是循环次数,k=logn,所有这个方法的时间复杂度可以即为O(logn)
空间复杂度
常量O(1)
提交结果:
二分查找的局限性
既然提到了二分查找,顺便说一下二分查找的局限性:
- 依赖有序数组
如果数组是无需的,那无法通过区间的缩小来界定目标值的位置,想要对无需数组二分查找的话,需要先排序,如果使用复杂度O(nlogn)的排序,时间复杂度就没法保证O(logn),而且会导致原数组的顺序变化。
- 依赖数组
二分查找通过数组下标查找数据,如果是链表的话,就没有快速找到指定的值
- 数据太大不适合
由于依赖数组,数组使用的是连续空间,如果数组过大,也就是连续的内存空间会很长,比如说2G的空间,这样用数组存储都是不太合适的,也就不适合用二分查找了。
最近面试,时间少,暂时只想到一种解法,先这样,Good Lock