首页 > 其他分享 >【STL】二分搜索的实现与stl标准库的应用

【STL】二分搜索的实现与stl标准库的应用

时间:2024-03-01 10:22:05浏览次数:40  
标签:二分 STL bound stl int num 搜索 key

在算法题中经常会出现搜索的题目,如果使用暴力搜索在数据量较大时会超时,(如\(10^5\)数量级时\(O(n^2)\)就会超时,\(O(nlogn)\)则通常不会),因此常用二分搜索等进行优化。
虽然stl库中关于二分搜索的接口很好用,很适合区间二分搜索,但我们仍需掌握C++实现二分搜索,“虽然这是一个简单的算法,但它的细节却惊人的可怕。”

1. C++实现二分搜索

AcWing 789. 数的范围 为例:
题目描述:
给定一个按照升序排列的长度为n的整数数组,以及q个查询。对于每个查询,返回一个元素k的起始位置和终止位置(位置从0开始计数)。如果数组中不存在该元素,则返回-1 -1。(数据范围\(10^5\))

#include <iostream>
using namespace std;
const int N=1e5+5;
int n,m,q[N];
int main ()
{
    cin>>n>>m;
    for (int i=0;i<n;i++) scanf("%d",&q[i]);
    while (m--)
    {
        int k;
        scanf("%d",&k);
        int l=-1, r=n;
        while(l+1!=r)
        {
            int mid=l+r>>1;
            if (q[mid]>=k) r=mid;
            else  l=mid;
        }
        if (q[r]!=k) printf("-1 -1\n");
        else
        {
            printf("%d ",r);
            int ll=-1,rr=n;
            while (ll+1!=rr)
            {
                int mid=ll+rr>>1;
                if (q[mid]<=k) ll=mid;
                else rr=mid;
            }
            if (q[ll]!=k) printf("%d\n",r);
            else printf("%d\n",ll);
        }
    }
    return 0;
}

r和ll分别逼近k范围的第一个数和最后一个数,r不存在说明k在数组中不存在。
使用stl接口实现版本较C++实现版慢5ms,差别不大。

2. 使用STL函数实现二分搜索

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int num[5] = {3, 1, 2, 5, 4};
    int key = 3;
    //二分搜索要求数组必须是有序的
    sort(num,num+5);
    // 第一个小于key的数的下标
    int a = lower_bound(num, num + 5, key) - num - 1;//利用减去起始位置指针的方式转换为int下标
    // 第一个大于key的数的下标
    int b = upper_bound(num, num + 5, key) - num;
    cout << a << ' ' << b << endl;
    //查找某个值是否存在
    cout << binary_search(num, num+5, 6);
    return 0;
}
输出:
1 3
0

注意:

  1. lower_bound和upper_bound返回的是迭代器(指针)
  2. lower_bound和upper_bound默认数组是升序的,若数组是降序排列必须用
	lower_bound(num, num + 5, key, greater<int>());
  1. 若查找值不存在,lower_bound和upper_bound返回第一个插入查找值而不影响原序列顺序的位置
  2. 调用函数前数组必须有序,若数组顺序和函数顺序不符/无序,会返回出错(-1或n)

相关知识

使用std::sort实现降序排序
实现1:bool cmp()

bool cmp(int x,int y)
    return x>y;

实现2:

sort(num,num+5,greater<int>());//降序
sort(num,num+5,less<int>());//升序

标签:二分,STL,bound,stl,int,num,搜索,key
From: https://www.cnblogs.com/liu-yc/p/18046121

相关文章

  • 洛谷题单指南-二分查找与二分答案-P2440 木材加工
    原题链接:https://www.luogu.com.cn/problem/P2440题意解读:切出来的长度越短,则段数越多,可以通过二分长度来解决。解题思路:二分的关键在于判定条件,此题就是对二分到的长度计算可以切割的段数,如果段数大于等于k,则满足要求,可以继续加大长度。注意点:1、计算切割出来的段数是累加:每......
  • 整数二分算法(自用)
    1.思想对于一个已排序数组,找到一个点,使得数组被分为两部分,即此点左部和右部(点在左部或右部中的一个),比如数组中小于等于某数x的部分与大于的部分;对于整数二分而言两个范围之间是没有空隙的,即左部分的边界x的下一个数一定在右部分。我们可以根据题目选择多种方法二分数组,大类上分......
  • 二分
    二分查找模板总结二分查找是一种在有序数组中查找某一特定元素的搜索算法。元素集合有顺序,元素性质有分界点,二分法就可以用来求分界点,并不一定要求集合中元素是不重复的。算法思路:假设目标值在闭区间[left,right]中,每次将区间长度缩小一半,当left=right时,我们就找到了......
  • 洛谷题单指南-二分查找与二分答案-P1678 烦恼的高考志愿
    原题链接:https://www.luogu.com.cn/problem/P1678题意解读:要计算不满意度之和的最小值,就要保证每个人的不满意度最小,即选择的学校录取分数-学生分数之差的绝对值最小。解题思路:如何在学校录取分数中找与学生分数最接近的呢?有三种可能:1、学生分数在录取分数中存在相等的2、学......
  • 洛谷题单指南-二分查找与二分答案-P1102 A-B 数对
    原题链接:https://www.luogu.com.cn/problem/P1102题意解读:寻找A-B=C的数对数量,C大于0,B一定比A小,枚举B,找A是否存在即可。解题思路:先将数据由小到大排序,接下来介绍两种方法:二分、双指针1、二分枚举第1~n-1个数,作为B,寻找A=B+C的数量,只需要通过二分查找第一A和最后一个A的位置l、......
  • CF514D R2D2 and Droid Army(二分,ST表)
    传送门解题思路直接二分能干掉的人数,然后check函数枚举所有区间,因为m很小,所以可以用m个ST表预处理每个区间对应每个属性的最大值。一是需要注意二分的写法,而是注意check(0)时候的特判。AC代码#include<iostream>#include<algorithm>#include<cmath>#include<cstdio>#......
  • 【STL和泛型编程】3. set、map分析(及typename起源)
    前置知识:红黑树原理 【数据结构】7.平衡搜索树(AVL树和红黑树),红黑树的平衡性有利于search和insert红黑树的迭代器begin()左侧end()右侧迭代顺序56781011121315不能使用迭代器修改Key的值,例如将6改成50会破坏红黑树的性质1.RB-tree在g++编译......
  • 洛谷题单指南-二分查找与二分答案-P2249 【深基13.例1】查找
    原题链接:https://www.luogu.com.cn/problem/P2249题意解读:找有序数组中某个数第一次出现的位置,二分模版题,由于是二分板块的第一题,有必要对二分的各种模版进行介绍。解题思路:关于二分的一切:1、二分的本质二分的本质,是通过某种判定把目标范围划分成两个区间二分问题通常有两......
  • 二分查找——修补木桶
    修补木桶-HihoCoder1362-VirtualJudge(vjudge.net)#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>usingnamespacestd;#defineintlonglong#defineQAQ0constintN=2e5+5,inf=0x3f3f3f3f,mod=1e7+7;int......
  • 数仓的等待视图中,为什么会有Hashjoin-nestloop
    本文分享自华为云社区《GaussDB(DWS)等待视图之Hashjoin-nestloop》,作者:Arrow0lf。1.业务场景众所周知,GaussDB(DWS)中有3种常见的join方式:HashJon/MergeJoin/NestLoop但在有一些场景中,等待视图中等待状态会显示为:HashJoin-nestloop,如下图所示。这种表示什么含义?2.基本原理......