LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置
思路
题目想让我们找到目标值的最小下标和最大下标,而这又是一个升序排列的数组,很明显用二分查找是最快的。
实现细节
二分查找是有标准库函数的,「lower_bound()」 是通过二分查找到第一个大于等于目标值的位置,「upper_bound()」 则是找到第一个大于目标值的位置,假设二者的结果分别为 和 ,最终的结果就是-。
特别地,如果原数组中不含有目标值,那么我们得到的 ,显然不满足题意,所以需要进行特判。
如果是手写二分的话,目标值的最小下标和最大下标实现上的区别在于:最小下标的查找中,当 时,应该移动右边界,这样才能保证我们要找的最小下标一直在范围内。
代码
(1)STL实现
class Solution {public: vector<int> searchRange(vector<int>& nums, int target) { int pos1 = lower_bound(nums.begin(),nums.end(),target) - nums.begin(); int pos2 = upper_bound(nums.begin(),nums.end(),target) - nums.begin(); if(pos1 == pos2) return {-1, -1}; vector<int> ans; ans.push_back(pos1); ans.push_back(pos2 - 1); return ans; }};
(2)手写二分实现
class Solution {public: vector<int> searchRange(vector<int>& nums, int target) { int l = 0, r = nums.size() - 1; int pos1 = nums.size(); while(l <= r){ int mid = (l+r)>>1; if(nums[mid] >= target) pos1 = mid,r = mid - 1; else l = mid + 1; } l = 0, r = nums.size() - 1; int pos2 = nums.size(); while(l <= r){ int mid = (l+r)>>1; if(nums[mid] > target) pos2 = mid , r = mid - 1; else l = mid + 1; } if(pos1 == pos2) return {-1, -1}; return {pos1, pos2 - 1}; }};
复杂度分析
时间复杂度:,只需要两次二分搜索
空间复杂度: