本文已参与「新人创作礼」活动,一起开启掘金创作之路。
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 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 <= 10^4 -10^4 <= nums[i] <= 10^4 nums 为无重复元素的升序排列数组 -10^4 <= target <= 10^4
思路:
首先先来一个不用动脑子的,直接暴力!来个for循环,直到找到大于等于target的值,输出下标;
显而易见,题目描述的是一个排序数组所以可以使用二分查找。使用二分查找的时候需要注意边界条件,看你使用的while条件是什么来判断后面的左右指针的加减。
代码区1(暴力):
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int n = nums.size();
for(int i= 0;i<n;i++){
if(nums[i]>=target)//找到大于的时候说明没有符合的数所以输出此处的下标就可以代表应当插入的位置,如果是等于就说明找到了,直接输出下标就可以了
return i;
}
return n;/如果没有提前返回的话说明没有大于等于目标值的数,所以目标数应该是最大的那个,所以插入在最后,返回n
}
};
代码区2(二分查找1):
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left=0;int right=nums.size();//此处定义的右边界是不存在的,下面需要注意
while(left<right){//因为右边界是开的,所以没有等于
int mid=(left+right)/2;
if(nums[mid]<target){
left=mid+1;//当该值小于目标值的时候说明还在右边,所以将左边界往右移
}
else if(nums[mid]>target){
right=mid;//此处不用加一,注意right是开的,所以不用+1
}
else return mid;//如果等于的话就直接返回mid
}
return right;//如果都不满足,说明目标值是最大的,所以要插在最后面,因为right是开的边界所以直接返回right就可以了,代表的是数组最后一个元素的下一个位置
}
};
代码区3(二分查找2):
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left=0;int right=nums.size()-1;//和上面不一样,这次dingy die两个边界都是闭合的
while(left<=right){//所以这里使用小于等于来当作while循环的条件
int mid = (left+right)/2;
if(nums[mid]<target){
left=mid+1;//目标值在右边,所以移动左边界
}else if(nums[mid]>target){
right=mid-1;//目标值在左边,所以移动右边界
}else return mid;//等于的话就直接返回mid
}
return right+1;//说明目标值最大,所以要插入的位置就是右边界的下一个位置,因为右边界是真实存在的,闭合的,所以+1就可以了
}
};
新手上路,有错请指正;