详解二分法查找目标值/二分法查找上下界的两种写法

2024-04-02 14:20

本文主要是介绍详解二分法查找目标值/二分法查找上下界的两种写法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文中默认数组呈升序。

💡 绝对不能使用left = cur这种更新,由于整数除法取下界,left不更新会导致循环无法结束

寻找与target相等

  1. 可以用(l < r)写法,末尾r==l需要检查是否满足条件,满足则输出,不满足则输出-1
  2. 可以用(l<=r) 写法,末尾输出r 不需要检查是否满足条件,不满足的情况下r为-1,因此结果r可能会超出数组索引,注意不要对此进行nums[r]的检查
// ==
// Method1 : left=mid+1, right=mid, 此时最优解为最后的重合解(若可行)
// 遍历直至left = right,左右重合时退出循环,此时重合解若可行,即为答案
int BinSearch1(vector<int> &nums, int target) {int l = 0;int r = nums.size()-1;int mid;while (l < r) {mid = (l+r)/2;if (nums[mid] == target)return mid;else if (nums[mid] < target) {l = mid + 1;}elser = mid;}if (nums[r] == target)return r;return -1;
}// ==
// Method2 : left=mid+1, right=mid-1, 此时最优解需要另外记录
// 遍历直至left > right,左右重合时仍然进入循环并进行结果记录
int BinSearch2(vector<int> &nums, int target) {int l = 0;int r = nums.size()-1;int mid;while (l <= r) {mid = (l+r)/2;if (nums[mid] == target)return mid;else if (nums[mid] < target) {l = mid + 1;}elser = mid - 1;}return r;
}

寻找第一个小于(等于)target

💡 需要使用(l<=r) 的写法

因为查找≤时不满足条件更新的是右界,满足条件下更新左界;

如果采用(l<r)写法:

  • 更新左界如果使用l = mid+1 ,由于mid此时满足条件,会导致新区间错失满足条件的点,答案错误
  • 如果使用l=mid,由于mid=(l+r)/2整数除法取下界,某些情况下左界会不更新,从而引起循环无法结束,程序错误

综上,在升序区间查找≤时只能采用(l≤r) 的写法,并通过r输出最终结果:若无满足条件的元素,将会使得r==-1

// <
int BinLBound(vector<int> &nums, int target) {int l = 0;int r = nums.size()-1;int mid;while (l <= r) {mid = (l+r)/2;// 先更新不满足条件if (nums[mid] >= target) {r = mid - 1;}elsel = mid + 1;}return r;
}// <=
int BinLEBound(vector<int> nums, int target) {int l = 0;int r = nums.size()-1;int mid;while (l <= r) {mid = (l+r)/2;if (nums[mid] > target)r = mid - 1;elsel = mid + 1;}return r;
}

寻找第一个大于(等于)target

  1. 可以用(l<r)
  2. 可以用(l<=r)
// >
int BinHBound(vector<int> &nums, int target) {int l = 0;int r = nums.size()-1;int mid;while (l < r) {mid = (l+r)/2;if (nums[mid] <= target)l = mid + 1;elser = mid;}if (nums[r] > target)return r;return -1;
}
// >=
int BinHEBound(vector<int> &nums, int target) {int l = 0;int r = nums.size()-1;int mid;while (l < r) {mid = (l+r)/2;if (nums[mid] < target)l = mid + 1;elser = mid;}if (nums[r] >= target)return r;return -1;
}

整体测试代码

#include <iostream>
#include <vector>using namespace std;int main()
{vector<int> nums{-5, 0, 1, 2, 5, 10, 30, 90};int target = 90;cout << BinSearch1(nums, target) << " " << BinSearch2(nums, target) << endl;cout << BinLBound(nums, target)  << " " << BinLEBound(nums, target) << endl;cout << BinHBound(nums, target)  << " " << BinHEBound(nums, target);return 0;
}

这篇关于详解二分法查找目标值/二分法查找上下界的两种写法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/870213

相关文章

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

MyBatis常用XML语法详解

《MyBatis常用XML语法详解》文章介绍了MyBatis常用XML语法,包括结果映射、查询语句、插入语句、更新语句、删除语句、动态SQL标签以及ehcache.xml文件的使用,感兴趣的朋友跟随小... 目录1、定义结果映射2、查询语句3、插入语句4、更新语句5、删除语句6、动态 SQL 标签7、ehc

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

Java中的.close()举例详解

《Java中的.close()举例详解》.close()方法只适用于通过window.open()打开的弹出窗口,对于浏览器的主窗口,如果没有得到用户允许是不能关闭的,:本文主要介绍Java中的.... 目录当你遇到以下三种情况时,一定要记得使用 .close():用法作用举例如何判断代码中的 input