34. Search for a Range (Array; Divide-and-Conquer)
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]
.
思路:先二分法找最左端,再二分法找最右端。保证稳定排序。具体实现:
- 相同元素返回最左元素:start从-1开始,且总是在<target位置,最后会是最左侧=target元素之前的那个位置
- 相同元素返回最右元素:end总是在>target位置,所以从n开始,最后会是最右侧=target元素之后的那个位置
结束条件:start+1==end
class Solution { public: vector<int> searchRange(vector<int>& nums, int target) { leftBinarySearch(nums,-1,nums.size()-1,target);//start始终在<target的位置 if(result[0]!=-1) rightBinarySearch(nums,0,nums.size(),target);//end始终在>target的位置 return result; } void leftBinarySearch(vector<int>& nums, int start, int end, int target){ if(start+1==end){ //结束条件:只剩两个数(因为此时mid==start,会进入死循环) if(target == nums[end]){ result.push_back(end); } else { result.push_back(-1); result.push_back(-1); } return; } int mid = start + ((end-start)>>1); if(target <= nums[mid]) leftBinarySearch(nums,start,mid,target); else leftBinarySearch(nums,mid, end,target); //start始终在<target的位置 } void rightBinarySearch(vector<int>& nums, int start, int end, int target){ if(start+1==end){ //must have one answer, so don't need if(target == nums[start]) result.push_back(start); return; } int mid = start + ((end-start)>>1); if(target < nums[mid]) rightBinarySearch(nums,start,mid,target); //end始终在>target的位置 else rightBinarySearch(nums,mid, end,target); } private: vector<int> result; };