首页 > 其他分享 >二分查找(整数二分)

二分查找(整数二分)

时间:2023-10-11 23:44:25浏览次数:39  
标签:二分 int mid 整数 查找 数组 区间

一、算法简介

二分法,即二分搜索法,是通过不断缩小解可能存在的范围,从而求得问题最优解的方法。

例如,如果一个序列是有序的,那么可以通过二分的方法快速找到所需要查找的元素,相比线性搜索要快不少。

此外二分法还能高效的解决一些单调性判定的问题。

  • 二分的关键不在于单调性,或者说二分的本质并不是单调性。
  • 二分的本质是能否找到一个性质使得左右两个区间的元素分别满足性质和不满足性质。
  • 二分到最后一定可以得到一个结果,lr是相同的,但是要判断是否满足题目条件。

二分算法思路非常简单,但是我们需要特别注意的是下标问题,相信很多人都会遇到二分死循环的问题,所以建议大家背一个模板,又快又准确,保证不会出错的解题。

以下介绍两个模板,区别仅在于l = mid时,mid需要加一,否则会出现死循环:

区间分为:[l, mid]和[mid + 1, r]
while (l < r)
{
    int mid = (l + r) >> 1;
    if (check(mid))	r = mid;
    else	l = mid + 1;
}
区间分为:[l, mid - 1]和[mid, r]
while (l < r)
{
    int mid = (l + r + 1) >> 1;
    if (check(mid)) l = mid;
    else	r = mid - 1;
}

二、题目描述

给定一个按照升序排列的长度为 \(n\) 的整数数组,以及 \(q\) 个查询。

对于每个查询,返回一个元素 \(k\) 的起始位置和终止位置(位置从 \(0\) 开始计数)。

如果数组中不存在该元素,则返回 -1 -1

输入格式

第一行包含整数 \(n\) 和 \(q\),表示数组长度和询问个数。

第二行包含 \(n\) 个整数(均在 \(1\) ~ \(10000\) 范围内),表示完整数组。

接下来 \(q\) 行,每行包含一个整数 \(k\),表示一个询问元素。

输出格式

共 \(q\) 行,每行包含两个整数,表示所求元素的起始位置和终止位置。

如果数组中不存在该元素,则返回 -1 -1

数据范围

\(1 ≤ n ≤ 100000\)
\(1 ≤ q ≤ 10000\)
\(1 ≤ k ≤ 10000\)

输入样例:

6 3
1 2 2 3 3 4
3
4
5 

输出样例:

3 4
5 5
-1 -1 

三、原题链接

AcWing789.数的范围

四、算法思路

  • 对于第一轮找起始位置,也就是找到≥x的最小值,所以可以将区间分为左区间<x,右区间≥x
  • 第一轮二分之后要判断是否满足条件,因为有可能数组中没有这个数,这个时候就要根据题目要求进行判断。
  • 对于第二轮找终止位置,也就是找到≤x的最大值,所以可以将区间分为左区间≤x,右区间>x

五、源码

#include <iostream>

using namespace std;

const int N = 100010;

int n, q;
int a[N];

int main()
{
    cin >> n >> q;
    
    for (int i = 0; i < n; ++i) cin >> a[i];
    
    while (q -- )
    {
        int x;
        cin >> x;
        
        int l = 0, r = n - 1;
        while (l < r)
        {
            int mid = (l + r) >> 1;
            if (a[mid] >= x)    r = mid;
            else    l = mid + 1;
        }
        
        if (a[l] != x)  cout << "-1 -1" << endl;
        else
        {
            cout << l << ' ';
            int l = 0, r = n - 1;
            while (l < r)
            {
                int mid = (l + r + 1) >> 1;
                if (a[mid] <= x)    l = mid;
                else    r = mid - 1;
            }
            cout << r << endl;
        }
    }
    
    return 0;
}

标签:二分,int,mid,整数,查找,数组,区间
From: https://www.cnblogs.com/grave-master/p/17758488.html

相关文章

  • 代码随想录算法训练营第一天(python) | 704. 二分查找、27. 移除元素。
    Leetcode704二分查找题目链接:704二分查找关键点思路:1、是否要进入到while部分的代码是left<=right还是left<right,看[left,right]是否是合法区间.例如[1,1]是合法区间,取<=;[1,1)非合法区间,取<。2、缩小区间时,考虑边界是否已经比较过。左闭右闭区......
  • C++黑马程序员——P223-226. set容器 构造和赋值,大小和交换,插入和删除,查找和统计
    P223.set容器——构造和赋值P224.set容器——大小和交换P225.set容器——插入和删除P226.set容器——查找和统计P223.set容器构造和赋值特点:所有元素都会在插入时自动被排序本质:set/multiset属于关联式容器,底层结构是用二叉树实现。set和multiset的区别set不......
  • 解决利用plt.plot绘图时,横坐标出现浮点小数而不是整数的情况(坐标轴刻度)
    解决利用plt.plot绘图时,横坐标出现浮点小数而不是整数的情况(坐标轴刻度)在使用matplotlib库的plt.plot函数进行绘图时,有时会遇到横坐标出现浮点小数的情况,而我们希望的是整数刻度。这可能会导致图表的可读性降低,因此需要解决这个问题。问题描述假设我们有一个数据集,横坐标表示时......
  • antd Input 只能输入大于零的正整数
    onChange={(value:any)=>{letval=Number(value);if(val<1){value='';setDeviceNumber('');}else{setDeviceNumber(Number(value.replace(/[^\d]/g,'')));}}}......
  • 判断整数和复数的奇技淫巧
      记得大一学Python的时候,有一个题目是判断一个数是否是复数。当时觉得比较复杂不好写,就琢磨了一个偷懒的好办法,用异常处理的手段便可以大大程度帮助你简短代码(偷懒)。以下是判断整数和复数的两段小代码:  相信看到这里,你也有所顿悟,能拓展出更多有意思的方法~......
  • python查找替换危险字符脚本
    为了沃滴好大儿的大创写了这么个脚本代码如下:1importio2importbase6434defreplace_dangerous_sequences(image_path):5try:6#读取图像文件的内容7withopen(image_path,'rb')asimage_file:8image_data=image_......
  • 搜索算法:线性搜索、二分法
    搜索算法:1.线性搜索:循环遍历,判断是否等于目标值2.二分法:(需要有序)先定一个起点和终点left,right,当left<right时,取中间值mid,如果目标值小于mid,则right=mid-1,反之亦然#线性搜索defaction1(arr,target):foriinarr:ifi==target:print(arr.inde......
  • 递归查找目录下的所有txt文件
    #include<dirent.h>#include<fcntl.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/stat.h>#include<sys/types.h>#include<unistd.h>intgetTxtNum(constchar*path){//打开目录......
  • day 1 数组 704.二分查找、27.移除元素
    704.二分查找题目链接:704.二分查找视频教程文章教程思路利用middle去寻找target前提条件:这道题目的前提是数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,二分查找法返回的元素下标可能就不唯一,这些都是二分法的前提,以后看到题目描述后可以先想一想......
  • 计算32位二进制整数中1的个数(包括负数补码)
    引言:在计算机科学和编程中,位操作是一项重要的技能。一个常见的任务是计算一个32位二进制整数中1的个数,包括负数的补码表示。这个问题有多种解决方法,本博客将介绍一种高效的解决方案,同时提供详细的代码案例。背景知识:在正整数的二进制表示中,1的个数表示了这个数的二进制形式中有多少......