35. 搜索插入位置
35. 搜索插入位置
题目:35. 搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 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
思路
本题的要求是查找到目标值在数组中的位置,如果不存在,返回它将会被顺序插入的位置。所以套用二分算法的模板即可。
代码
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int n = nums.size();
int l = 0, r = n;
while (l < r) {
int mid = l + (r - l) / 2;
if (target > nums[mid]) {
l = mid + 1;
} else if (target < nums[mid]) {
r = mid;
} else if (target == nums[mid]) {
r = mid;
}
}
return l;
}
};
优化
二分算法很简单,但细节是魔鬼。
从下面几点解释其他版本的代码与上述代码的区别:
- 为什么 r = n,r = n - 1 不行吗
这是由于 while 循环体内的条件决定的,l < r 就意味着搜索区间是左闭右开区间。因此如果使 r = n - 1,代码会产生一个小 bug 。即示例3所示,当 target > nums[n - 1] 时,由于搜索区间的限制,无法返回 n。
所以可以在开始的地方加入判断,即可解决此 bug。
if(target > nums[n - 1]) return n;
- while 中的判断条件是 \(l <= r\) 可以吗
可以,此时搜索区间就是左闭右闭区间。习惯来说,使用 \(l < r\) 从搜索区间中排查元素,结束循环后再进行检查。而 \(l<=r\) 则是从搜索区间中查找元素,遇到符合条件的直接返回。
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int n = nums.size();
int l = 0, r = n - 1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (target > nums[mid]) {
l = mid + 1;
} else if (target < nums[mid]) {
r = mid - 1;
} else if (target == nums[mid]) {
return mid;
}
}
return l;
}
};

浙公网安备 33010602011771号