二分查找

二分查找

image

image

默认升序,找到从左到右第一个比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;
        }
    }
};

image

image

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};
         }
    }
};

image

image

本题代码:

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;
}

 image

image

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);
    }
};

image

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];
    }
};

 

posted @ 2025-12-07 20:11  Annaprincess  阅读(2)  评论(0)    收藏  举报