题目描述
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例:
输入: [1,3,5,6], 5
输出: 2
输入: [1,3,5,6], 2
输出: 1
输入: [1,3,5,6], 7
输出: 4
题目链接:https://leetcode-cn.com/problems/search-insert-position/
思路1
由于数组是有序的,所以可以直接遍历数组,当当前元素大于等于目标值时,返回当前元素的下标即可。代码如下:
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
if(nums.empty())
return 0;
for(int i=0; i<nums.size(); i++){
if(nums[i]>=target) // 等于就返回当前下标i,大于返回要插入的下标,也是i
return i;
}
return nums.size();
}
};
- 时间复杂度:O(n)
遍历数组一遍,所以为O(n). - 空间复杂度:O(1)
申请的额外内存不随输入规模的增大而增大。
思路2
题目中出现了“有序数组”并且是查找问题,所以可以利用二分查找来做。整个流程和二分查找一致,当中间元素等于目标值时,返回下标。如果查找结束没有找到目标值,则返回left的下标。代码如下:
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
if(nums.empty())
return 0;
int left=0, right=nums.size();
while(left<right){
int mid = (left+right)/2;
if(nums[mid]==target)
return mid;
else if(nums[mid]<target)
left=mid+1;
else right=mid;
}
return left;
}
};
- 时间复杂度O(logn)
二分查找的时间复杂度为O(logn). - 空间复杂度O(1)
总结
当题目为查找问题,并且是在排序数组上进行查找,通常使用二分查找解决。二分查找想着容易,但很难一次性写对,因为边界条件不好控制,需要单独多写几遍。二分查找模板:https://leetcode-cn.com/problems/search-insert-position/solution/hua-jie-suan-fa-35-sou-suo-cha-ru-wei-zhi-by-guanp/