LeetCodehot100-34. 在排序数组中查找元素的第一个和最后一个位置
class Solution {
public:
int search(vector<int>& nums, int target){//>=
int left=0,right=nums.size()-1;
while(left<=right){
int mid=left+(right-left)/2;
if(nums[mid]<target) left=mid+1;
else right=mid-1;
}
return left;
}//[0, left-1] 中的所有元素都 < target
//[right+1, n-1] 中的所有元素都 >= target
//结束时 left = right + 1
vector<int> searchRange(vector<int>& nums, int target) {
int start=search(nums,target);
if(start==nums.size()||nums[start]!=target) return {-1,-1};
int end=search(nums,target+1)-1;//第一个 >= target+1 的位置,必然等于第一个 > target 的位置,
//这个位置的前一个位置,就是最后一个 == target 的位置
return {start,end};
}
};
Leetcode162. 寻找峰值
class Solution {
public:
int findPeakElement(vector<int>& nums) {
int left=0,right=nums.size()-2;//// 假设 nums.size() = 5,索引 0-4 right = 3
// 循环中 mid 最大为 3
// mid+1 最大为 4,安全 ✓
while(left<=right){
int mid=left+(right-left)/2;
if(nums[mid]>nums[mid+1]) right=mid-1;//明下坡,峰值在左侧(包括 mid)
else left=mid+1;//说明上坡,峰值在右侧
}
return left;
}
};
Leetcode153. 寻找旋转排序数组中的最小值
class Solution {
public:
int findMin(vector<int>& nums) {
int left=0,right=nums.size()-2;//// 假设 nums.size() = 5,索引 0-4 right = 3
// 循环中 mid 最大为 3
// mid+1 最大为 4,安全 ✓
while(left<=right){
int mid=left+(right-left)/2;
if(nums[mid]>nums[nums.size()-1]) left=mid+1; //mid 在左半部分(较大的部分),最小值在右边
else right=mid-1;// mid 在右半部分(较小的部分),最小值在左边(包括 mid)
}
return nums[left];
}
};
Leetcode33. 搜索旋转排序数组
两次二分查找
class Solution {
public:
int search(vector<int>& nums, int target) {
int left=0,right=nums.size()-1,sz=right;
while(left<=right){
int mid=left+(right-left)/2;
if(nums[mid]>nums[sz]) left=mid+1;
else right=mid-1;
}//此时left指向最小值的地方
if (target > nums[sz]) {
// target 在左半区 [0, left-1]
right = left - 1;
left = 0;
} else {
// target 在右半区 [left, sz]
right = sz;
}
while(left<=right){
int mid=left+(right-left)/2;
if(nums[mid]==target) return mid;
else if(nums[mid]<target) left=mid+1;
else right=mid-1;
}
return -1;
}
};