首页 > 其他分享 >二分浅入

二分浅入

时间:2022-11-30 12:12:16浏览次数:40  
标签:二分 arr right 浅入 mid value int left

二分

前言

仅看要点不是很能理解,主要是看示例

要点总结复习用

要点

  1. 关注范围,需要的是\([left,right]\)还是\([left,right)\)
  2. 定义最后 \(l\) 和 \(r\) 落点位置是什么
  3. 根据落点,描述循环不变式,即 \(l\) 的左边恒为 什么, \(r\) 的右边恒为 什么

例子

LowerBound

在 求非严格递增序列中,求第一个大于等于 \(value\) 的数的下标

定义循环结束后 \(l\) 落在第一个大于等于 \(value\) 的数的位置,则循环不变量为:

  1. \(R\) 的右边(不含\(R\))一定是大于等于 \(value\) 的
  2. \(L\) 的左边(不含\(L\))一定是小于 \(value\) 的

若定义左闭右闭区间

// left 落在第一个大于等于 value 的数的位置
public static int lowerbound(int[] arr, int left, int right, int value) {
    //左闭右闭
    //如arr下标从0~n-1,则left=0,right=n-1
    //如果区间不为空
    while (left <= right) {
        int mid = left + right >> 1;
        //mid位置的数小于value,则[left,mid]一定都是小于value的,根据循环不变量 L左边一定是小于value的
        //又由于区间是左闭的,所以left指向mid + 1
        if (arr[mid] < value) left = mid + 1;
        //否则mid位置的数大于等于value,则[mid+1,right]都是大于等于value的,根据循环不变量 R右边一定是大于等于value的
        //又由于是右闭的,所以right指向mid - 1
        else right = mid - 1;
    }
    return left;
}

若定义左闭右开区间

// left 落在第一个大于等于 value 的数的位置
public static int lowerbound(int[] arr, int left, int right, int value) {
    //左闭右开
    //如arr下标从0~n-1,则left=0,right=n
    //如果区间不为空
    while (left < right) {
        int mid = left + right >> 1;
        //mid位置的数小于value,则[left,mid]一定都是小于value的,根据循环不变量 L左边一定是小于value的
        //又由于区间是左闭的,所以left指向mid+1
        if (arr[mid] < value) left = mid+1;
        //否则mid位置的数大于等于value,则[mid+1,right)都是大于等于value的,根据循环不变量 R右边一定是大于等于value的
        //又由于是右开的,所以right指向mid
        else right = mid;
    }
    return left;
}

UpperBound

在 求非严格递增序列中,求第一个大于 \(value\) 的数的下标

定义循环结束后 \(l\) 落在第一个大于 \(value\) 的数的位置,则循环不变量为:

  1. \(R\) 的右边(不含\(R\))一定是大于 \(value\) 的
  2. \(L\) 的左边(不含\(L\))一定是小于等于 \(value\) 的

若定义左闭右闭区间

// left 落在第一个大于 value 的数的位置
public static int upperbound(int[] arr, int left, int right, int value) {
    //左闭右闭
    //如arr下标从0~n-1,则left=0,right=n-1
    //如果区间不为空
    while (left <= right) {
        int mid = left + right >> 1;
        //mid位置的数小于等于value,则[left,mid]都是小于等于 value 的
        //根据循环不变量,left左边都是小于等于value的
        //左闭区间,left指向mid+1
        if (arr[mid] <= value) left = mid + 1;
        //否则mid位置的数大于value,则[mid,right]都是大于 value 的
        //根据循环不变量,right右边都是大于 value 的
        //右闭区间,right指向mid-1
        else right = mid - 1;
    }
    return left;
}

若定义左闭又开区间

// left 落在第一个大于 value 的数的位置
public static int upperbound(int[] arr, int left, int right, int value) {
    //左闭右开
    //如arr下标从0~n-1,则left=0,right=n
    //如果区间不为空
    while (left < right) {
        int mid = left + right >> 1;
        //mid位置的数小于等于value,则[left,mid]都是小于等于 value 的
        //根据循环不变量,left左边都是小于等于value的
        //左闭区间,left指向mid+1
        if (arr[mid] <= value) left = mid + 1;
        //否则mid位置的数大于value,则[mid,right)都是大于 value 的
        //根据循环不变量,right右边都是大于 value 的
        //右开区间,right指向mid
        else right = mid;
    }
    return left;
}

标签:二分,arr,right,浅入,mid,value,int,left
From: https://www.cnblogs.com/Cattle-Horse/p/16938033.html

相关文章

  • 拓端tecdat|R语言代码编写对二分连续变量进行逻辑回归数据分析
    R语言对二分连续变量进行逻辑回归数据分析​教育或医学的标准情况是我们有一项连续的措施,但随后我们对那些具有临床/实践意义的措施有了切入点。一......
  • 二分查找
    二分查找:请对一个有序数组进行二分查找{1,8,10,89,1000,1234},输入一个数看看该数组是否存在此数,并且求出下标,如果没有就提示"没有这个数"。二分查找思路二分查......
  • ACM预备队-week5(DFS/BFS/二分图)
    [蓝桥杯2013国C]危险系数题目链接:P8604[蓝桥杯2013国C]危险系数-洛谷|计算机科学教育新生态(luogu.com.cn)割点:删除这个顶点集合以所有顶点相关联的边以......
  • 二分查找-LeetCode704 简单题
    LeetCode代码链接:https://leetcode.cn/problems/binary-search/题目:给定一个 n 个元素有序的(升序)整型数组 nums和一个目标值 target ,写一个函数搜索 nums 中的t......
  • 二分查找总结
    二分查找二分查找也常被称为二分法或者折半查找(BinarySearch),每次查找时通过将待查找区间分成两部分并只取一部分继续查找,将查找的复杂度大大减少。对于一个长度为O(n) ......
  • LOJ #6044 题解——完全二分图的生成树计数
    LOJ#6044显然就是要求有多少左边有\(K\)个点,右边有\(N-K\)个点的完全二分图的生成树个数,但是我不会!所以我们想一想怎么算左边\(n\)个点,右边\(m\)个点的完全二分......
  • IM通讯协议专题学习(三):由浅入深,从根上理解Protobuf的编解码原理
    本文由码农的荒岛求生陆小风分享,为了提升阅读体验,进行了较多修订和排版。1、引言搞即时通讯IM方面开发的程序员,在谈到通讯层实现时,必然会提到网络编程。那么计算机网络......
  • 整数二分查找
    总的来说使用二分的条件:具有单调性注意:二分的思想看似简单,但其实很容易出错整数二分模板以单调递增序列的二分为例给出两个模板:在单调递增序列中找到x或x的后继(大于......
  • 【Core Java Volume 6】集合算法--二分查找法
    在数组中查找一个对象,当数组是有序的时候可以采用二分查找法。即可以直接查看位于数组中间的元素,看一看是否大于查找的元素。如果大于,用同样的方法在数组的前半部分继续查找......
  • 4383 [八省联考 2018] 林克卡特树(WQS 二分+DP)
    P4383[八省联考2018]林克卡特树给定一颗\(n\)个点的树,每条边有边权\(v(|v|\le10^6)\),要求删去其中任意\(k\)条边,使得剩余联通块的直径之和最大。求出这个最大值......