[算法][二分查找][排除法]

最基本的二分查找算法

在这里插入图片描述
「搜索区间」是 [left, right]
nums[mid] == target 时可以立即返回

int binary_search(int[] nums, int target) {int left = 0, right = nums.length - 1; while(left <= right) {int mid = left + (right - left) / 2;//防止大数溢出if (nums[mid] < target) {left = mid + 1;} else if (nums[mid] > target) {right = mid - 1; } else if(nums[mid] == target) {// 直接返回return mid;}}// 直接返回return -1;
}

在这里插入图片描述

普通版寻找左侧边界的二分查找

「搜索区间」是 [left, right)
{1,2,2,2,3}
nums[mid] == target 时不要立即返回,要收紧右侧边界以锁定左侧边界

int left_bound(int[] nums, int target) {int left = 0, right = nums.length - 1;while (left <= right) {int mid = left + (right - left) / 2;if (nums[mid] < target) {left = mid + 1;} else if (nums[mid] > target) {right = mid - 1;} else if (nums[mid] == target) {// 别返回,锁定左侧边界right = mid - 1;}}// 最后要检查 left 越界的情况if (left >= nums.length || nums[left] != target)return -1;return left;
}

普通版寻找右侧边界的二分查找

「搜索区间」是 [left, right)
{1,2,2,2,3}
nums[mid] == target 时不要立即返回,收紧左侧边界以锁定右侧边界

int right_bound(int[] nums, int target) {int left = 0, right = nums.length - 1;while (left <= right) {int mid = left + (right - left) / 2;if (nums[mid] < target) {left = mid + 1;} else if (nums[mid] > target) {right = mid - 1;} else if (nums[mid] == target) {// 别返回,锁定右侧边界left = mid + 1;}}// 最后要检查 right 越界的情况if (right < 0 || nums[right] != target)return -1;return right;
}

排除法思考二分法

在这里插入图片描述
1、确定搜索区间初始化时候的左右边界,有时需要关注一下边界值。在初始化时,有时把搜索区间设置大一点没有关系,但是如果恰好把边界值排除在外,再怎么搜索都得不到结果。

2、无条件写上 while (left < right) ,表示退出循环的条件是 left == right,对于返回左右边界就不用思考了,因此此时它们的值相等;

3、先写下取整的中间数取法,然后从如何把 mid 排除掉的角度思考 if 和 else 语句应该怎样写。

(这里建议写两个注释。)

  • 一般而言,我都会把**“什么时候不是目标元素”**作为注释写在代码中,提醒自己要判断正确,这一步判断非常关键,直接影响到后面的代码逻辑。
  • 然后接着思考 mid 不是解的情况下,mid 的左右两边可能存在解,把下一轮搜索的区间范围作为注释写进代码里,进而在确定下一轮搜索区间边界的收缩行为时,不容易出错。

if 有把握写对的情况下,else 就是 if 的反面,可以不用思考,直接写出来。

** 说明:这种思考方式,就正正好把待搜索区间从逻辑上分成两个区间,一个区间不可能存在目标元素,进而在另一个区间里继续搜索,更符合“二分”的语义。**

4、根据 if else 里面写的情况,看看是否需要修改中间数下取整的行为。
在这里插入图片描述
在这里插入图片描述
上面已经说了,只有看到 left = mid 的时候,才需要调整成为上取整,记住这一点即可,我因为刚开始不理解这种写法,遇到很多次死循环,现在已经牢记在心了。
在这里插入图片描述

5、退出循环的时候,一定有 left == right 成立。有些时候可以直接返回 left (或者 right,由于它们相等,后面都省略括弧)或者与 left 相关的数值,有些时候还须要再做一次判断,判断 left 与 right 是否是我们需要查找的元素,这一步叫“后处理”。

// 有可能区间内不存在目标元素,因此还需做一次判断if (nums[left] == target) {return left;}return  -1;
public int searchInsert(int[] nums, int target) {int len = nums.length;if (len == 0) {return 0;}int left = 0;// 因为有可能数组的最后一个元素的位置的下一个是我们要找的,故右边界是 lenint right = len;while (left < right) {int mid = (left + right) >>> 1;// 小于 target 的元素一定不是解if (nums[mid] < target) {// 下一轮搜索的区间是 [mid + 1, right]left = mid + 1;} else {right = mid;}}return left;}

在这里插入图片描述
在这里插入图片描述

二分查找模板 一般步骤

在这里插入图片描述

与其他二分查找的比较

在这里插入图片描述
在这里插入图片描述

[总结]

1.普通版

-左右移动下标时,mid下标对应的值已经作为比较,故坐标更新时需要加一减一

2.防止大数溢出
  • mid = left + (right - left) / 2
3.完整掌握二分查找需要注意细节,善用排除法

参考链接:https://github.com/Arthashuo/fucking-algorithm/blob/master/%E7%AE%97%E6%B3%95%E6%80%9D%E7%BB%B4%E7%B3%BB%E5%88%97/%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE%E8%AF%A6%E8%A7%A3.md

参考链接:https://leetcode-cn.com/problems/search-insert-position/solution/te-bie-hao-yong-de-er-fen-cha-fa-fa-mo-ban-python-/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/426034.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java学习(147):字节输入流

//读取二进制文件&#xff0c;字节输入流 import java.io.*;public class FileMana {public static void readBitFile(String filename){//1建立目标要读取的文件对象File filenew File( filename );//2基于目标对象建立输入流InputStream innull;if(file.exists()){//如果文件…

[Leedcode][JAVA][面试题 01.07][找规律][旋转数组]

【问题描述】 [面试题 01.07. 旋转矩阵] 示例 1:给定 matrix [[1,2,3],[4,5,6],[7,8,9] ],原地旋转输入矩阵&#xff0c;使其变为: [[7,4,1],[8,5,2],[9,6,3] ]给你一幅由 N N 矩阵表示的图像&#xff0c;其中每个像素的大小为 4 字节。请你设计一种算法&#xff0c;将图像…

java学习(148):三个参数的输入流

//3个参数读取二进制文件 import java.io.*;public class FileManage {public static void readBitFile(String filename){//1建立目标要读取的文件对象File filenew File( filename );//2基于目标对象建立输入流InputStream innull;if(file.exists()){//如果文件存在&#xff…

[剑指offer][JAVA][面试题第13题][机器人的运动][DFS][BFS]

【问题描述】 [中等] 地上有一个m行n列的方格&#xff0c;从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动&#xff0c;它每次可以向左、右、上、下移动一格&#xff08;不能移动到方格外&#xff09;&#xff0c;也不能进入行坐标和列坐标的数位之和…

ios php rsa,RSA 加密 iOS

在iOS端使用RSA加密的记录一、需求&#xff1a;SDK开发&#xff0c;使用RSA加密和后台进行数据交互&#xff0c;后台是PHP要求&#xff1a;1、post请求&#xff0c;客户端放公钥&#xff0c;私钥放后台2、发送数据&#xff1a;客户端的json数据—>RSA加密数据—>base64编…

java学习(149):字符输入流

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

java三年,Java开发三年,你不得不了解的JVM(一)

基本概念&#xff1a;JVM 是可运行 Java 代码的假想计算机 &#xff0c;包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收&#xff0c;堆 和 一个存储方法域。JVM 是运行在操作系统之上的&#xff0c;它与硬件没有直接的交互。运行过程&#xff1a;我们都知道Java源文件…

[Leedcode][JAVA][第22题括号生成][DFS][BFS][动态规划]

【问题描述】22. 括号生成 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 示例&#xff1a;输入&#xff1a;n 3 输出&#xff1a;["((()))","(()())","(())()","()(…

java学习(150):文本缓冲流

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

微信小程序初始化 operateWXData:fail invalid scope

初学者开发微信小程序&#xff0c;可以使用云开发来进行微信小程序的开发。 第一次使用开发工具遇到的问题 解决方案&#xff1a;1、找到云开发 2、点击开通&#xff0c;选择合适自己的开发环境&#xff1b; 3、完成后&#xff0c;返回开发工具界面点击项目第一个节点“cloudfu…

matlab win10 gpu加速,win10的Edge浏览器设置GPU硬件加速,大幅度提升浏览器性能

不知道大家对于GPU硬件加速是否有了解&#xff0c;这是现在的浏览器必备的功能&#xff0c;开启后能大幅度提升浏览器的性能&#xff0c;给我们更加顺滑的浏览体验。GPU硬件加速能够利用GPU的图形性能&#xff0c;加速渲染网页中的图像信息。如果我们开启了GPU硬件加速&#xf…

java学习(151):字节输出流

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

[Leedcode][JAVA][第887题][鸡蛋掉落][谷歌面试][动态规划]

【问题描述】 [887. 鸡蛋掉落] 你将获得 K 个鸡蛋&#xff0c;并可以使用一栋从 1 到 N 共有 N 层楼的建筑。每个蛋的功能都是一样的&#xff0c;如果一个蛋碎了&#xff0c;你就不能再把它掉下去。你知道存在楼层 F &#xff0c;满足 0 < F < N 任何从高于 F 的楼层落…

java学习(152):字节缓冲输出流

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

SDUTOJ3469_深度优先搜索练习之神奇的矩环(DFS)

深度优先搜索练习之神奇的矩环 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description 小鑫的女朋友被魔王抢走了&#xff01; 魔王留给小鑫一张n*m大的表&#xff0c;上面有各种各样的颜色&#xff0c;用A-Z这26个字母来表示。魔王留给他一个任务…

PHP水果店管理系统,水果店连锁店管理系统实现一体化功能

现在的人们越来越注重养生&#xff0c;特别是饮食养生那么水果就成为了客户的首选之一&#xff0c;随着水果的市场需求越来越大&#xff0c;想开水果店的创业者越来越多&#xff0c;连锁水果店我们看到的店面也越来越多&#xff0c;由于季节或者是时间的问题会很容易导致水果变…

[剑指offer]面试题第[58]题[Leetcode][JAVA][第151题][翻转单词][字符串常用函数总结]

【问题描述】 给定一个字符串&#xff0c;逐个翻转字符串中的每个单词。示例 1&#xff1a; 输入: "the sky is blue" 输出: "blue is sky the"【解答思路】 1. 双指针 倒序遍历字符串确定边界添加单词拼接字符串 返回 时间复杂度&#xff1a;O(N) 空间…

java学习(153):字符输出流

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

java学习(154):文件复制

import javax.imageio.IIOException; import java.io.*; import java.util.Date;//字符输入流 public class FileManagerChar {public static void readCharFile(File file){FileReader fileReadernull;//文本输入流if(file.exists()){try {fileReader new FileReader( file )…

[Leedcode][JAVA][面试题 16.03. 交点]

【问题描述】面试题 16.03. 交点 给定两条线段&#xff08;表示为起点start {X1, Y1}和终点end {X2, Y2}&#xff09;&#xff0c;如果它们有交点&#xff0c;请计算其交点&#xff0c;没有交点则返回空值。要求浮点型误差不超过10^-6。若有多个交点&#xff08;线段重叠&am…