题目要求:
给定一个排好顺序数组和一个目标值,搜索数组,如果找到目标,那么返回索引。如果没有,那么返回该目标值应该插入数组的位置索引。
假设数组中没有重复项。
Example:
例1 输入: [1,3,5,6], 5 输出:2
例2 输入: [1,3,5,6], 2 输出:1
例3 输入: [1,3,5,6], 7 输出:4
例4 输入: [1,3,5,6], 0 输出:0
解题思路
1.暴力遍历法
如果找到目标值,那么返回索引,如果没找到,也很简单,只要返回第一个比目标值大的元素索引即可。时间复杂度较高,不推荐。
主要代码C++
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
for(int i = 0; i< nums.size(); i++)
if (nums[i] == target) return i;
for(int i = 0; i<nums.size(); i++)
if(nums[i] > target) return i;
return nums.size();
}
};
2.二分查找法
二分法的思想是计算当前区间的中间元素的值,把区间分成两部分,然后与target比较,然后根据比较结果决定下一次在前区间还是后区间进行查找
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int start = 0;
int end = nums.size() - 1;
while(start<=end)
{
int mid = start + (end - start)/2;
if(nums[mid] < target)
start = mid + 1;
else
end = mid - 1;
}
return start;
}
};
3. lower_bound()法
在讨论区看到的骚操作,确实挺好用的,一行代码解决战斗。
lower_bound()和upper_bound()都是利用二分查找的思想,在一个排好顺序(正好题目满足要求)的数组中查找。
lower_bound(), upper_bound()区别:
lower_bound(begin,end,target),找到第一个大于或等于目标值的数,返回地址,通过减去起始地址begin,得到数字在数总中的下标。
upper_bound(begin,end,target),找到第一个大于(没有等于!!)目标值的数,返回地址,通过减去起始地址begin,得到数字在数总中的下标。看下代码:
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
` return lower_bound(nums.begin(), nums.end(), target) - nums.begin();
}
};