class Solution {public: int searchNum(vector<int>& nums, int ll, int rr, int target){ int l = ll, r = rr; //搜索左边的边界点,题目会出现没有旋转的情况【1】,【1,3】 //这种情况你利用num[mid] < mus[0]找右边界点会有问题 while(l < r){ int mid = l + r >> 1; if(nums[mid] >= target) r = mid; else l = mid + 1; } return nums[r] == target ? r : -1; } int search(vector<int>& nums, int target) { int l = 0, r = nums.size() - 1; while(l < r){ int mid = l + r + 1 >> 1; if(nums[mid] >= nums[0]) l = mid; else r = mid - 1; } if(target >= nums[0]){ return searchNum(nums, 0, l, target); }else{ return searchNum(nums, l+1, nums.size() - 1, target); } }};
class Solution {
public:
bool search(vector<int>& nums, int target) {
if(nums.empty()) return false;
int R = nums.size() - 1;
//1. 针对全是一样的情况,【2,2,2,2】,留一个,继续执行后面的查找
while(R > 0 && nums[R] == nums[0]) R--;
//2. 针对全是一样的情况,一个不留,立即特判一下,不符合就不执行后面的了
// while (R >= 0 && nums[R] == nums[0]) R -- ;
// if (R < 0) return nums[0] == target;
int l = 0, r = R;
while(l < r){
int mid = l + r + 1 >> 1;
if(nums[mid] >= nums[0]) l = mid;
else r = mid - 1;
}
if(target >= nums[0]) {r = l; l = 0;}
else {l++; r = R;}
while(l < r){
int mid = l + r >> 1;
if(nums[mid] >= target) r = mid;
else l = mid + 1;
}
return nums[r] == target;
}
};
class Solution {
public:
int findMin(vector<int>& nums) {
int l = 0, r = nums.size() - 1;
if(nums[r] >= nums[0]) return nums[0];
while(l < r){
int mid = l + r >> 1;
if(nums[mid] < nums[0]) r = mid;
else l = mid + 1;
}
return nums[r];
}
};
class Solution {
public:
int findMin(vector<int>& nums) {
if(nums.empty()) return false;
int R = nums.size() - 1;
//没有旋转
if(nums[R] > nums[0]) return nums[0];
//删除末尾和nums[0]一样的
while(R >= 0 && nums[R] == nums[0]) R--;
if(R < 0) return nums[0];
int l = 0, r = R;
while(l < r){
int mid = l + r >> 1;
if(nums[mid] < nums[0]) r = mid;
else l = mid + 1;
}
return nums[r];
}
};
//【1,2,1】过不去
#------------------------------------------------------------------
class Solution {
public:
int findMin(vector<int>& nums) {
if(nums.empty()) return false;
int R = nums.size() - 1;
//删除末尾和nums[0]一样的
//R > 0留一个数,应对只有一个数的情况【1】
while(R > 0 && nums[R] == nums[0]) R--;
//针对上面【1,2,1】的情况,下面返回的其实是第一个1,但是也计算出了答案
//如果是找出旋转的下标,这样就不对了
if(nums[R] > nums[0]) return nums[0];
int l = 0, r = R;
while(l < r){
int mid = l + r >> 1;
if(nums[mid] < nums[0]) r = mid;
else l = mid + 1;
}
return nums[r];
}
};
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.empty()) return {-1,-1};
int l = 0, r = nums.size() - 1;
vector<int> res;
while(l < r){
int mid = l + r >> 1;
if(nums[mid] >= target) r = mid;
else l = mid+1;
}
if(nums[r] != target){return {-1,-1};}
else{
res.push_back(r);
l = 0; r = nums.size() - 1;
while(l < r){
int mid = l + r + 1 >> 1;
if(nums[mid] <= target) l = mid;
else r = mid - 1;
}
res.push_back(r);
}
return res;
}
};
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
if(nums.empty()) return 0;
int l = 0, r = nums.size() - 1;
while(l < r){
int mid = l + r >> 1;
if(nums[mid] >= target) r = mid;
else l = mid + 1;
}
//【1,3,5】插入7,插入位置就要是最后一个下标+1了
return nums[r] >= target ? r : r + 1;
}
};
//把r设置为r = nums.size();就不用特判了,两种都可以,上面的好理解一点
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
if(nums.empty()) return 0;
int l = 0, r = nums.size();
while (l < r) {
int mid = l + r >> 1;
if (nums[mid] >= target) r = mid;
else l = mid + 1;
}
return r;
}
};
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if(matrix.empty() || matrix[0].empty()) return false;
int m = matrix.size(), n= matrix[0].size();
int l = 0, r = m * n - 1;
while(l < r){
int mid = l + r >> 1;
if(matrix[mid / n][mid % n] >= target) r = mid;
else l = mid +1;
}
return matrix[r / n][r % n] == target;
}
};
class Solution {
public:
int findPeakElement(vector<int>& nums) {
int l = 0, r = nums.size() - 1;
while(l < r){
int mid = l + r >> 1;
if(nums[mid] > nums[mid+1]) r = mid;
else l = mid + 1;
}
return r;
}
};
//这题和下面一题看的有点迷迷糊糊的,还要再看
class Solution {
public:
int hIndex(vector<int>& c) {
if(c.empty()) return 0;
sort(c.begin(), c.end(), greater<int>());
//[6,5,3,1,0]
//h > 0 不是h >= 0是因为我们也要对【0,0,0】这样的数据判断
for(int h = c.size(); h > 0; h--){
//c[h-1]表示最小的数,如果最小的数都大于等于h
//那就证明数组中一定有h个数大于等于h
//我们要找的就是就是这个h
if(c[h-1] >= h) return h;
}
return 0;
}
};
//------------------------------------
//正向排序与下面的题结合起来
class Solution {
public:
int hIndex(vector<int>& c) {
if(c.empty()) return 0;
sort(c.begin(), c.end());
int n = c.size();
if(c[n - 1] == 0) return 0;
int l = 0, r = n - 1;
while(l < r){
int mid = l + r >> 1;
if(c[mid] >= n-mid) r = mid;
else l = mid + 1;
}
return n - r;
}
};
//上一题因为要排序,已经是nlogn了,没有必要在二分了
//现在排好序了,就可以降到logn了
class Solution {
public:
int hIndex(vector<int>& c) {
int n = c.size();
int l = 0, r = n;
while(l < r){
int mid = l + r + 1 >> 1;
if(c[n-mid] >= mid) l = mid;
else r = mid - 1;
}
return r;
}
};
//---------------------------------------
//这个逻辑更好理解一点https://www.acwing.com/solution/content/2806/
class Solution {
public:
int hIndex(vector<int>& c) {
int n = c.size();
if(n == 0 || c[n - 1] == 0) return 0;
int l = 0, r = n - 1;
while(l < r){
int mid = l + r >> 1;
if(c[mid] >= n-mid) r = mid;
else l = mid + 1;
}
return n - r;
}
};
class Solution {
public:
int firstBadVersion(int n) {
int l = 0, r = n;
while(l < r){
//2126753390
//1702766719 可能会有溢出,要转换一下
int mid = (long)l + r >> 1;
if(isBadVersion(mid)) r = mid;
else l = mid + 1;
}
return r;
}
};
class Solution {
public:
vector<int> findRightInterval(vector<vector<int>>& q) {
//一共有多少个区间
int n = q.size();
//把每个区间的下标,放在每个区间的最后
for(int i = 0; i < n; i++) q[i].push_back(i);
//把所有区间排序
sort(q.begin(), q.end());
//结果,如果没有找到,结果就是-1,找到了后面会覆盖
vector<int> res(n, -1);
//枚举每个区间
for(auto& x: q){
int l = 0, r = n - 1;
while(l < r){
int mid = l + r >> 1;
//mid的左端点,大于等于当前区间的又端点
if(q[mid][0] >= x[1]) r = mid;
else l = mid + 1;
}
//判断找到的那个区间是否符合条件
if(q[r][0] >= x[1]){
//当前下标的值等于找到的区间的下标值
res[x[2]] = q[r][2];
}
}
return res;
}
};