二分查找
二分查找


默认升序,找到从左到右第一个比target小的数mid,插入到他后一位(mid+1)
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int l=0;
int r=nums.size()-1;
if(target>nums[r])return r+1;
else{
while(l<r){
int mid=(l+r)>>1;
if(target<=nums[mid]){
r=mid;
}
else{
l=mid+1;
}
}
return l;
}
}
};


class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int l=0;
int r=nums.size()-1;
if(nums.size()==0)return {-1,-1};
//第一个数
while(l<r){//退出循环l==r
int mid=(l+r)>>1;
if(target<=nums[mid]){
r=mid;
}
else{
l=mid+1;
}
}
// cout<<l;
//最后一个数
int l1=0;
int r1=nums.size()-1;
while(l1<r1){//退出循环l1==r1
int mid1=(l1+r1+1)>>1;
if(target>=nums[mid1]){
l1=mid1;
}
else{
r1=mid1-1;
}
}
// cout<<l1<<endl;
//l为第一个数,l1为最后一个数
if(nums[l]!=target)return {-1,-1};
else{
return {l,l1};
}
}
};


本题代码:
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int h = matrix.size();
int l = matrix[0].size();
for (int i = 0; i < h; i++) {
auto it = lower_bound(matrix[i].begin(), matrix[i].end(), target);
if (it != matrix[i].end()) {
if (*it == target)
return true;
}
}
return false;
}
};
总结:
对于一个递增序列:
1.lower_bound(matrix[i].begin(), matrix[i].end(), target);返回第一个>=target的元素的指针,找不到返回end,找到*it就是指针对应的元素值
2.upper_bound返回第一个大于target的元素的指针,
对于一个递减序列
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> vec = {7, 5, 3, 3, 1}; // 降序
int val = 3;
// 降序下:lower_bound找第一个<=3的元素(因为comp是a>b,!comp(*it,val)即*it<=val)
auto it_lower = lower_bound(vec.begin(), vec.end(), val, greater<int>());
// 降序下:upper_bound找第一个<3的元素(comp(*it,val)即*it<val)
auto it_upper = upper_bound(vec.begin(), vec.end(), val, greater<int>());
cout << "lower_bound指向:" << *it_lower << ",索引:" << it_lower - vec.begin() << endl;
cout << "upper_bound指向:" << *it_upper << ",索引:" << it_upper - vec.begin() << endl;
return 0;
}


class Solution {
public://因为时间复杂度要O(log n)所以
int searchhelpers(vector<int>&nums,int left,int right,int target){
if(right<left){//没找到
return -1;
}
int mid=(left+right)/2;
int midvalue=nums[(left+right)/2];
int leftvalue=nums[left];
int rightvalue=nums[right];
if(leftvalue==target)return left;
if(rightvalue==target)return right;
if(midvalue==target)return mid;
//mid左边有序的
if(leftvalue<midvalue){//target在左边的范围内
if(target>leftvalue&&target<midvalue){
return searchhelpers(nums,left+1,mid-1,target);
}
else{//在右边
return searchhelpers(nums,mid+1,right-1,target);
}
}
//mid右边有序
else{
if(target>midvalue&&target<rightvalue){
return searchhelpers(nums,mid+1,right-1,target);
}
else{
return searchhelpers(nums,left+1,mid-1,target);
}
}
}
int search(vector<int>& nums, int target) {
return searchhelpers(nums,0,nums.size()-1,target);
}
};

class Solution {
public:
int findMin(vector<int>& nums) {
int high=nums.size()-1;
int low =0;
while(low<high){
int mid=low+(high-low)/2;
if(nums[mid]<nums[high]){
high=mid;
}
else{
low=mid+1;
}
}
return nums[low];
}
};

浙公网安备 33010602011771号