搜索插入位置
题目链接:LeetCode 搜索插入位置.35
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 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
提示:
1 <= nums.length <=
- <= nums[i] <=
nums 为 无重复元素 的 升序 排列数组
- <= target <=
思路:
本题可以理解为查找大于等于target的第一个数。
设立两个指针left和right。
middle=(left+right)/2。
如果判断target等于nums[middle]或target在nums[middle]的左边,则更新右指针为middle。
否则target就在nums[middle]的右边,则更新左指针为middle+1。
循环到left==right,循环终止。
最后得出的答案则为第一个不小于target的数组元素的下标,等同于查找成功时返回目标值的元素下标,查找失败则返回第一个大于目标值的元素下标。
代码:
class Solution
{
public:
int searchInsert(vector<int> &nums, int target)
{
int left = 0, right = nums.size();
while (left < right)
{
// 防止溢出,等同于(left + right)/2
int middle = left + ((right - left) >> 1);
// nums[middle]==target或者nums[middle]在target的左边
if (target <= nums[middle])
{
right = middle;
}
// nums[middle]在target的右边
else
{
left = middle + 1;
}
}
return left;
}
};
解释:
因为target可能插在最后一个数组元素后面,如果right取nums.size()-1的话取不到。并且middle取不到nums.size(),程序不会出错,所以right取nums.size()。
left + ((right - left) >> 1)==(left + right) / 2
因为left+right可能溢出,(right-left)使用减法不会超出最大的整型范畴,所以使用第一种方法可以防止溢出。
>>是右移运算符,右移一位等于除以2,右移n位等于除以2的n次方。