目录
题目:
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 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
题解
在排序数组中寻找一个目标值,第一方法是二分法在O(logn)时间内找到目标值,本题还要考虑数组中不存在目标值的情况下需要返回按顺序插入的位置,需要将二分法稍微改进一下:
nums[pos-1] < target < nums[pos]
代码(cpp & python)
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int len = nums.size();
int left = 0,right = len-1;
while (left <= right){
int mid = left + (right - left)/2;
if (target <= nums[mid]){
right = mid - 1;
}
else{
left = mid + 1;
}
}
return left;
}
};
执行用时:4 ms, 在所有 C++ 提交中击败了82.27%的用户
内存消耗:9.5 MB, 在所有 C++ 提交中击败了12.19%的用户
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
n = len(nums)
left,right = 0,n-1
while (left <= right):
mid = left + int((right-left)/2)
if target <= nums[mid]:
right = mid - 1
else:
left = mid + 1
return left
执行用时: 36 ms
内存消耗: 15.5 MB
拓展(二分法)
二分法查找原理:
针对一个有序数组,当我们需要搜索某一个目标数时,我可以一个一个进行遍历搜索,但是,这样会浪费太多计算机资源,并且效率较低,因此,我们需要一个更加高效的方式进行搜索.
二分法查找是指将目标数与有序数组的中间数进行比较,如果中间数大于目标数,则说明目标数在中间数的前面,反之则在中间数后面,再以中间数的前半部(或者后半部)为一个新数组,取中间数与目标数判断,再取新数组再判断,如此循环下去后,直到中间数等于目标数,这样,目标数便找到了。
二分法查找的时间复杂度O(logn)。
注1:
二分法查找适用于数据量较大时,但是数据需要先排好顺序;
一般先使用冒泡算法排好顺序,之后使用二分法查找目标值。
注2:
2-1: int mid = left + (right - left) / 2;
2-2: int mid = (right + left) / 2;
二分法有时使用2-1,有时使用2-2,因为:
有时 left 和 right 会有大小限制,可能 right + left 会导致栈溢出,使用2-1 可以避免这种情况,这就是你为什么可以看到二分法写法有的是2-1,有的是2-2了。
参考
https://blog.csdn.net/qq_41929184/article/details/108561044
The End!点个赞吧!