给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
因为题目要求的时间复杂度为O(log n),小编第一时间想到了二分法,但是二分法要求的数组必须是有序的,本题下方的提示说明本题可用二分法求解。如果用枚举的方法求解,时间复杂度为O(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
C语言
int searchInsert(int* nums, int numsSize, int target)
{
//设置前后指针
int start=0,end=numsSize-1;
//中间指针
int mid;
//循环体不断更新中间指针
while(start<=end)
{
//设置中间指针是前后指针的一半
mid=(start+end)/2;
//当目标小于数组中间的数时,在前指针和中间指针之间可能存在目标
if(target<nums[mid])
end=mid-1;
//当目标大于数组中间的数时,在后指针和中间指针之间可能存在目标
else if(target>nums[mid])
start=mid+1;
//目标和数组中间数匹配成功,返回中间数的下标
else
return mid;
}
//说明:当二分法查找失败时,目标会与最后中间指针的前一位或者后一位比较过
/*
程序执行到此时,说明数组中不存在目标
此时需要判断插入目标的位置
因为目标与数组进行的了多次比较
每次比较与数组中间指针所指向的数差值越来越小
此时差值最小
所以我们的目标要插值在中间指针的附近
当目标小于中间指针所指向的数时,目标就要插值在中间指针的位置
中间指针以后的数向后挪动一位
当目标大于中间指针指向的数字时
目标也与中间指针的后一位比较过,且小于中间指针的后一位
目标要插值在中间指针的后一位
*/
if(target>nums[mid])
return mid+1;
else
return mid;
}
python
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
end=len(nums)-1
start=0
while(start<=end):
mid=int((start+end)/2)
if nums[mid]>target:
end=mid-1
elif nums[mid]<target:
start=mid+1
else:
return mid
if nums[mid]>target:
return mid
else:
return mid+1
因为两个版本的结构一样,所以python不再过多赘述
枚举python
小编也写了一个枚举的办法,提交之后发现他的执行用时和内存消耗和二分法相差无几,可能是数据量太小,所以不太明显,代码如下,仅供参考!
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
l=len(nums)
for i in range(l):
if nums[i]==target:
return i
if i==0 and nums[0]>target:
return i
if i==l-1 and nums[i]<target:
return i+1
if i!=0:
if nums[i-1]<target and nums[i]>target:
return i