例题:35.搜索插入位置:
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
链接:https://leetcode.cn/problems/search-insert-position
示例 1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:
输入: nums = [1,3,5,6], target = 2
输出: 1
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums
为 无重复元素 的 升序 排列数组-104 <= target <= 104
思考:
该题与之前的704题类似,属于是704题二分查找的一个延伸,增加了要求:“如果目标值不存在于数组中,返回它将会被按顺序插入的位置。”
704题链接:https://leetcode.cn/problems/binary-search
所以只需要在704题查找的基础上,在未找到对应元素时,返回对应的值即可。所谓的顺序插入,而当没有找到对应值时,我们会发现,此时的left所在位置即为插入位置。
具体算法:
参考704题总结出来的二分查找各种方法,写了三种算法,分别为左闭右闭、左闭右开、左开右开。
左闭右闭:
int searchInsert(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while (left <= right) {
int mid = (right - left) / 2 + left;
int num = nums[mid];
if (num == target) {
return mid;
}
else if (num > target) {
right = mid - 1;
}
else {
left = mid + 1;
}
}
return left;
}
左闭右开:
int searchInsert2(vector<int>& nums, int target) {
int left = 0, right = nums.size();
while (left < right) {
int mid = (right - left) / 2 + left;
int num = nums[mid];
if (num == target) {
return mid;
}
else if (num > target) {
right = mid;
}
else {
left = mid + 1;
}
}
return left;
}
左开右开(通用模板):
int searchInsert3(vector<int>& nums, int target) {
int left = -1, right = nums.size();
while ((left + 1) != right)
{
int mid = (left + right) / 2;
if (nums[mid] < target)
{
left = mid;
}
else
{
right = mid;
}
}
return right;
}