20251020二分总结

引子

需要引子吗?

洛谷 P2249 【深基13.例1】查找

题目简化就是说给你n个单调不减的数,进行m次询问,每次询问给定一个数x,求x再这n个数当中最早出现的下标。

其实就是二分查找板子,只要套一下STL的二分查找函数就行了,或手搓二分查找;第二种做法就是用map充当桶数组。

在这里介绍一下二分查找函数:lower_bound以及upper_bound

其实都差不多,只不过lower_bound找的是序列里第一个大于等于这个数的下标,upper_bound找的是序列里第一个大于这个数的下标。

具体用法,()_bound(数组名+起始下标,数组名+结束下标,要找的数)-数组名

这道题用的肯定是lower_bound,首先用lower_bound查一遍要找的数,然后看找到的数跟要找的数是不是一样的。

时间复杂度O(mlogn)O(mlogn)O(mlogn)

cpp 复制代码
#include<bits/stdc++.h>//二分查找写法
using namespace std;
int a[1000005];
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    while(m--){
        int x;
        cin>>x;
        int y=lower_bound(a+1,a+1+n,x)-a;//有函数为什么还要手搓?
        if(x!=a[y]){//如果找到的数不是一样的
            cout<<-1<<" ";
        }else{
            cout<<y<<" ";
        }
    }
    return 0;
} 

map桶数组写法就是用一个map数组来记录每个数最早出现的下标,因为给的数组是单调不减的,所以只要看输入的数有没有被记录过,没记录过就更新就行了。

当然,还是因为给的数组是单调不减的,所以用unordered_map可以省那么一丢丢。

时间复杂度理想下O(n+m)O(n+m)O(n+m)

cpp 复制代码
#include<bits/stdc++.h>//map桶数组写法
using namespace std;
unordered_map<int,int> t;
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        if(!t[x]){//如果没记录过
            t[x]=i;
        }
    }
    while(m--){
        int x;
        cin>>x;
        if(!t[x]){//如果这个数没有出现过
            cout<<-1<<" ";
        }else{
            cout<<t[x]<<" ";
        }
    }
    return 0;
} 
相关推荐
fangzhanpeng1685 天前
快速掌握C#语言基础知识点(1.基础数据类型)
开发语言·c#·1024程序员节
无己心7 天前
面向多平台 AI 搜索引擎的适配层架构设计
前端·人工智能·搜索引擎·ai·1024程序员节
u01030552713 天前
AI驱动的安卓UI自动生成功能实现
人工智能·1024程序员节
u01030552713 天前
长株潭智能体赋能腾讯元器链接共享
1024程序员节
云贝贝贝15 天前
OceanBase认证体系介绍与备考指南
运维·服务器·oceanbase·1024程序员节
u01030552715 天前
Java图像处理实战指南
人工智能·1024程序员节
u01030552715 天前
Java AWT鼠标事件全解析
人工智能·1024程序员节
u01030552718 天前
Java实用类应用精讲
人工智能·1024程序员节
u01030552718 天前
Java I/O核心操作实战
人工智能·1024程序员节
u01030552719 天前
ArrayList操作详解与实战应用
人工智能·1024程序员节