首页 > 其他分享 >二分(折半查找)详细解答(边界条件终止条件等等详细解释)

二分(折半查找)详细解答(边界条件终止条件等等详细解释)

时间:2023-11-10 21:56:30浏览次数:29  
标签:折半 二分 right 数组 mid 边界条件 查找 详细 left

刷 Leetcode 总能遇到关于二分的题目,但是之前也只是草草地了解一下,每次在使用的时候都需要找模板,要不然就需要对于边界条件进行调试,着实是很麻烦!!!


二分介绍:

首先来简单介绍一下二分:二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求 线性表 必须采用 顺序存储结构,而且表中元素按关键字有序排列

优点:

  1. 比较次数少:二分查找每次将搜索范围缩小一半,因此比较次数较少,查找速度快。
  2. 时间复杂度低:在有序数组中,二分查找的时间复杂度为O(log n),其中n为搜索范围的大小。相比线性查找的O(n)时间复杂度,二分查找更高效。
  3. 可靠性高:由于二分查找是基于有序数组进行的,因此在数组有序的前提下,可以保证查找结果的准确性。

缺点:

  1. 要求有序数组:二分查找要求待查表为有序表,如果数组无序,则需要先进行排序操作,增加了额外的时间复杂度。
  2. 插入删除困难:由于二分查找是基于有序数组进行的,插入和删除操作会破坏数组的有序性,因此在插入和删除元素时需要维护数组的有序性,增加了操作的复杂度。
适用范围以及题型:

  在一段有序序列中寻找指定元素(或者该序列中不存在指定元素,返回小于等于指定元素的最大值)等等


二分法讲解:

arr数组为有序序列
left: 左边界 right:右边界 mid = (left + right) / 2: 中间下标 循环条件: left .. right

上述为二分中的左边界(left),右边界(right),中间元素下标(mid).

二分法分类:

1.闭区间(左边界 left = 0, 右边界 right = arr.size() - 1)

先插入代码:

        // 1 2 3 5 6 8 9 10(有序数组中的元素)
        int left = 0, right = arr.size() - 1;
        int goal = 5;while(left <= right){
            int mid = ( left + right) / 2;
            if(goal > arr[mid]){
                left = mid + 1;
            }else{
                right = mid - 1;
            } 
            cout << "Left:" << left << "  " << "Right:" << right << "     " ;
        }     
        cout << "结果是" << left << endl; 

我们直接进行分析(先不要想为什么这样子,先跟着我的思路走):
(1)闭区间初始化:
  left = 0, right = arr.size() - 1,则此时 left 和 right 代表的分别是数组序列的起始元素和末尾元素
(2)循环条件的设置:
  循环结束的标志是区间内没有元素,因此只有当 left < right 的时候才会终止,因此设置 while(left <= right)
(3)循环中 if 语句满足与不满足后的 left 和 right 的设置
  暂时不讨论为什么这样子设置

来看终止情况:
终止前的一次: left == right
设 X = left, Y = right (这里的X和Y是不会变的,因为此时 left == right,所以可以 X == Y)
此时 mid == X (或者Y),结果只有两种可能,goal对应元素下标为 (1)X对应的  或者 (2)X + 1对应的
    前面这句话不理解可以看 while 循环中的 if 语句,流程图如下:

 

接着我们分析两种情况:
情况一:X对应的元素是目标值
  则此时进入 if 语句,判断为 N,进入第二个执行语句: right = mid - 1, 则此时 left 不变,结果就是 left, 就是 X

情况二:X + 1对应的元素是目标值
  则此时进入 if 语句,判断为 Y,进入第一个执行语句:left = mid + 1,则此时结果仍然是 left, 就是 X + 1

综上:cout << l << endl; 就可以得到正确答案!


  

 

 



标签:折半,二分,right,数组,mid,边界条件,查找,详细,left
From: https://www.cnblogs.com/yysnff/p/17825156.html

相关文章

  • 学ai需要哪些基础知识,详细一点
    学习人工智能(AI)需要一系列广泛的基础知识,涉及数学、统计学、计算机科学和机器学习等领域。以下是一份详细的基础知识清单:数学基础:a. 线性代数:了解向量、矩阵、行列式、特征值等概念,因为它们在机器学习中经常出现。b. 微积分:理解导数和积分,因为它们是深度学习等算法的基础。......
  • hook技术原理,举个详细的例子,然后给大家比喻一下就懂了
    "Hook"技术,通常指的是一种在计算机编程中用于拦截、修改或扩展系统或应用程序行为的技术手段。它常用于软件开发中,通过在特定事件或函数调用的前后插入自定义代码,实现对系统或应用程序的控制和定制。这种技术在操作系统、图形用户界面(GUI)、网络通信、安全等领域广泛应用。原理概......
  • k8s部署业务服务(详细总结篇)
    1.业务部署说明我们是做算法的,每个算法会被封装成一个镜像,比如:image1(入侵算法),image2(安全带识别算) 结合k8s流程:ingress-nginx(做了hostNetwork:true 网络模式,省去了service的一成转发),直接可以访问ingress-nginx的域名和端口——>客户通过ingress发布的host+path+业务......
  • rpm包制作脚本spec文件编写详细指南
    概述spec文件是制作rpm包的脚本文件,详细定义rpm包的信息、包含内容和安装位置,如软件包的名字、版本、类别、说明摘要、创建时要执行什么指令、安装时要执行什么操作、以及软件包所要包含的文件列表等等。spec文件有多个段组成,分别定义rpm编译、打包、安装等阶段的工作内容。示例如......
  • vue-cli-service vue.config.js配置 productionSourceMap与webpack中的devtool 关联详
    https://webpack.js.org/configuration/devtool/https://cli.vuejs.org/zh/config/#productionsourcemap https://github.com/vuejs/vue-cli/blob/f0f254e4bc81ed322eeb9f7de346e987e845068e/packages/%40vue/cli-service/lib/config/prod.js#L7 可以在源码中看到if(pro......
  • 压缩包Zip格式详析(全网最详细)
    原文:https://blog.csdn.net/qq_43278826/article/details/118436116【前言】     Android的安装包.apk实际上就是个zip格式的压缩包,所以在了解apk签名之前,有必要先来探索一下zip格式压缩包的结构一、Zip格式结构图总览  二、Zip文件结构详解zip格式压缩包主要由......
  • Android并发编程高级面试题汇总(含详细解析 十二)
    Android并发编程高级面试题汇总最全最细面试题讲解持续更新中......
  • Android并发编程高级面试题汇总(含详细解析 十五)
    Android并发编程高级面试题汇总最全最细面试题讲解持续更新中......
  • 使用Python调用API接口获取拼多多商品数据:一篇详细说明文章
    一、引言拼多多是中国著名的电商平台之一,提供了丰富的商品信息和购物服务。为了更好地利用拼多多的数据资源,我们可以使用Python编程语言调用拼多多的API接口,获取商品数据并进行处理和分析。本文将详细介绍如何使用Python完成这一任务,包括API的基本概念、接口调用流程、代码实现和数......
  • 利用python实现京东商品详细信息
    实现京东商品详细信息爬虫可以分为以下几个步骤:发起HTTP请求获取商品页面HTML;使用网页解析库解析HTML,提取商品详细信息;存储提取的信息。下面是一个简单的Python示例,使用requests库发起HTTP请求,使用BeautifulSoup解析HTML,提取商品信息,最后将提取的信息存储到CSV文件......