34. Search for a Range
- Total Accepted: 91630
- Total Submissions: 308192
- Difficulty: Medium
Given a sorted array of integers, find the starting and ending position of a given target value.
Your algorithm's runtime complexity must be in the order of O(log n).
If the target is not found in the array, return [-1, -1]
.
For example,
Given [5, 7, 7, 8, 8, 10]
and target value 8,
return [3, 4]
.
思路:二分查找。至少有3个方法。
方法一先找到第一个元素值>=查找值的位置,然后向后遍历直到找到第一个元素值>查找值。
方法二找到第一个元素值>查找值的位置,然后向前遍历直到找到最后一个元素值>=查找值的位置。
方法三直接用STL的lower_bound()和upper_bound()函数找到左右边界,这两个函数都是左闭右开的,就是查找值不与函数第二个参数位置的数比较大小。
这里有2个二分查找的模板,都是在左闭右闭区间(也考虑最右元素值好查找值的大小),但要注意查找值不在元素值范围时的溢出情况:
1. 找到元素值>=查找值的第一个元素的位置,元素值全部小于查找值时,返回最右元素位置+1。见方法一。
2. 找到元素值>查找值的第一个元素的位置,元素值全部小于查找值时,返回最右元素位置+1。见方法二。
代码:
方法一:找到第一个元素值>=查找值的位置,然后向后遍历直到找到第一个元素值>查找值:
1 class Solution {
2 public:
3 vector<int> searchRange(vector<int>& nums, int target) {
4 int n=nums.size(),low=0,high=n-1,mid;
5 vector<int> res(2,-1);
6 while(low<=high){
7 mid=low+(high-low)/2;
8 if(nums[mid]<target){
9 low=mid+1;
10 }
11 else{
12 high=mid-1;
13 }
14 }
15 if(low<n&&nums[low]==target){
16 res[0]=low;
17 while(low<n&&nums[low]==target) low++;
18 res[1]=low-1;
19 }
20 return res;
21 }
22 };
方法二:找到第一个元素值>查找值的位置,然后向前遍历直到找到最后一个元素值>=查找值的位置:
1 class Solution {
2 public:
3 vector<int> searchRange(vector<int>& nums, int target) {
4 int n=nums.size(),low=0,high=n-1,mid;
5 vector<int> res(2,-1);
6 while(low<=high){//得到右边界,返回第一个大于target的位置或者溢出位置
7 mid=low+(high-low)/2;
8 if(nums[mid]<=target){
9 low=mid+1;
10 }
11 else{
12 high=mid-1;
13 }
14 }
15 if(low>0&&nums[--low]==target){
16 res[1]=low;
17 while(low>=0&&nums[low]==target) low--;
18 res[0]=low+1;
19 }
20 return res;
21 }
22 };
方法三:
1 class Solution { 2 public: 3 vector<int> searchRange(vector<int>& nums, int target) { 4 vector<int> res(2,-1); 5 vector<int>::iterator low,high; 6 low=lower_bound(nums.begin(),nums.end(),target);//[nums.begin(),nums.end()),左闭右开,返回元素值大于等于查找值的第一个位置 7 high=upper_bound(nums.begin(),nums.end(),target);//[nums.begin(),nums.end()),左闭右开,返回元素值大于查找值的第一个位置 8 if(low!=high){ 9 high--; 10 res[0]=low-nums.begin(); 11 res[1]=high-nums.begin(); 12 } 13 return res; 14 } 15 };