代码随想录刷题

二分

学习视频

cpp 复制代码
//模板
a[N]; //存数据
int l=-1,r=n;
while(l+1<r){
	int mid=l+r>>1;
	if(a[mid]<ans or a[mid]<=ans) l=mid;
	else r=mid;
}
return l  or  r;

示例

如何确定两个or处的选择,应该按照答案所处的边界位置划分为两个区域,暂且称之为含答案区域(绿色区域)与非含答案区域(白色)比如对于数据 1 2 2 3 3 3 5

1.找到第一个3的位置,绿色区域为 3 3 3 5,可以看出r指针会指向最终答案3(while结束的条件是l+1==r,二分结束后l与r指针分别指向左右边界的位置),所以l不可能是答案,所以第一个or的位置就是a[mid]< 3

2.找到最后一个3的位置,绿色区域为 1 2 2 3 3 3,可以看出l指针会指向最终答案3,所以第一个or处选择a[mid]<=3

3.找到比3小的最大的数,绿色区域为 1 2 2,可以看出l指针会指向最终答案2,所以第一个or处选择a[mid]< 3(因为最后l指针要指向答案,不能指向3所以不能带=)

4.找到比3大的最小的数,绿色区域为 5,可以看出r指针会指向最终答案5,所以第一个or处选择a[mid]<=3(因为r指针要指向最终答案,不能指向3)

cpp 复制代码
#include<iostream>
using namespace std;
const int N=1e5+10;
int a[N];
int n;
int main(){
    cin >> n;
    for(int i=1;i<=n;i++) cin >> a[i];
    int l=0,r=n+1;
    // //找到第一个3的位置
    // while(l+1<r){
    //     int mid=l+r>>1;
    //     if(a[mid]<3) l=mid;
    //     else r=mid;
    // }
    // cout <<r;
    
    // //找到最后一个3的位置
    // while(l+1<r){
    //     int mid=l+r>>1;
    //     if(a[mid]<=3) l=mid;
    //     else r=mid;
    // }
    // cout << l;
    
    // //找到比3小的最大的数
    // while(l+1<r){
    //     int mid=l+r>>1;
    //     if(a[mid]<3) l=mid;
    //     else r=mid;
    // }
    // cout << l;
    
    //找到比3大的最小的数
    while(l+1<r){
        int mid=l+r>>1;
        if(a[mid]<=3) l=mid;
        else r=mid;
    }
    cout << r;
    return 0;
}

Acwing 数的范围

cpp 复制代码
#include<iostream>
using namespace std;
const int N=1e5+10;
int a[N];
int q,n;
int main(){
    cin >> n >> q;
    for(int i=1;i<=n;i++) cin >> a[i];
    while(q--){
        int ans;
        cin >> ans;
        int l=0,r=n+1;
        while(l+1<r){
            int mid=l+r>>1;
            if(a[mid]<ans) l=mid;
            else r=mid;
        }
        if(a[r]!=ans) {
            cout << "-1 -1" << endl;
            continue;
        }
        cout << r-1 <<" ";
        l=0,r=n+1;
        while(l+1<r){
            int mid=l+r>>1;
            if(a[mid]<=ans) l=mid;
            else r=mid;
        }
        cout << l-1 << endl;
    }
    return 0;
} 

Acwing数的三次方根

cpp 复制代码
#include<iostream>
#include<cmath>
using namespace std;
double ans;
int main(){
    cin >> ans;
    double l=-10001,r=10001;
    while(abs(l*l*l-ans)>1e-9){
        double mid=(l+r)/2;
        if(mid*mid*mid<ans) l=mid;
        else r=mid;
    }
    printf("%.6f",l);
    return 0;
}

35. 搜索插入位置

cpp 复制代码
class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int l=-1,r=nums.size();
        while(l+1<r){
            int mid=l+r>>1;
            if(nums[mid]<=target) l=mid;
            else r=mid;
        }
        if(l==-1) return 0;
        if(nums[l]!=target){
            return l+1;
        }
        return l;
    }
};

34.在排序数组中查找元素的第一个和最后一个位置

cpp 复制代码
class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int l=-1,r=nums.size();
        nums.push_back(1e9+10);  //防止溢出
        while(l+1<r){
            int mid=(l+r)>>1;
            if(nums[mid]<target) l=mid;
            else r=mid;
        }
        int begin=r;
        if(nums[r]!=target){
            return {-1,-1};
        }
        l=-1,r=nums.size();
        while(l+1<r){
            int mid=(l+r)>>1;
            if(nums[mid]<=target) l=mid;
            else r=mid;
        }
        int last=l;
        return {begin,last};
    }
};
相关推荐
元亓亓亓7 分钟前
LeetCode热题100--240.搜索二维矩阵--中等
算法·leetcode·矩阵
明月看潮生1 小时前
青少年编程与数学 02-019 Rust 编程基础 09课题、流程控制
开发语言·算法·青少年编程·rust·编程与数学
oioihoii1 小时前
C++23 views::slide (P2442R1) 深入解析
linux·算法·c++23
yuhao__z1 小时前
代码随想录算法训练营第六十三天| 图论9—卡码网47. 参加科学大会,94. 城市间货物运输 I
算法·图论
June`2 小时前
专题三:穷举vs暴搜vs深搜vs回溯vs剪枝(全排列)决策树与递归实现详解
c++·算法·深度优先·剪枝
vlln2 小时前
适应性神经树:当深度学习遇上决策树的“生长法则”
人工智能·深度学习·算法·决策树·机器学习
冲帕Chompa3 小时前
图论part09dijkstra算法
算法·图论
·云扬·3 小时前
【PmHub后端篇】PmHub中基于Redis加Lua脚本的计数器算法限流实现
redis·算法·lua
周Echo周3 小时前
20、map和set、unordered_map、un_ordered_set的复现
c语言·开发语言·数据结构·c++·算法·leetcode·list
zkmall3 小时前
推荐算法工程化:ZKmall模板商城的B2C 商城的用户分层推荐策略
算法·机器学习·推荐算法