如何正确的写出二分查找算法

利用循环不变式写出正确的二分查找及其衍生算法 一.你能准确写出二分查找吗?先看看定义 二分查找的搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则查找成功;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。 思路很简单以至于大多数人都能讲出来,但是有多少人能一次写出bug-free的 阅读详情
查找届跟排序届不同,面试常用的算法就这么一种,二分查找。二分查找看似容易,其实写得完全正确还是挺难的,下面总结一下规律。

一个普通的二分查找
int search(vector<int>& v,int target){
    int left=0;
    int right=v.size()-1;
    while(left<=right){
        int mid=(left+right)/2;
        if(v[mid]<target)
            left=mid+1;
        else if(v[mid]>target)
            right=mid-1;
        else
            return mid;
    }
    return -1;
}

另外一种也很普通的二分查找
int search(vector<int>& v,int target){
    int left=0;
    int right=v.size();
    while(left<right){
        int mid=(left+right)/2;
        if(v[mid]<target)
            left=mid+1;
        else if(v[mid]>target)
            right=mid;
        else
            return mid;
    }
    return -1;
}
注意, int mid=(left+right)/2的时候有可能溢出,所以可以写成int mid=left+(right-left)/2;
二分查找真正的挑战来自于输入有序数组有很多重复的元素。
如果我们需要找重复元素的第一个
int search(vector<int>& v,int target){
    int left=0;
    int last=-1;
    int right=v.size();
    while(left<right){
        int mid=left+(right-left)/2;
        if(v[mid]<target)
            left=mid+1;
        else if(v[mid]>target)
            right=mid;
        else{
            last=mid;
            right=mid;
        }
    }
    return last;
}

还有一些变种,比如找小于某个数的第一个元素
int search(vector<int>& v,int target){
    int left=0;
    int last=-1;
    int right=v.size();
    while(left<right){
        int mid=left+(right-left)/2;
        if(v[mid]<target){
            last=mid;
            left=mid+1;
        }
        else{
            right=mid;
        }
    }
    return last;
}
<script>window._bd_share_config={"common":{"bdsnskey":{},"bdtext":"","bdmini":"2","bdminilist":false,"bdpic":"","bdstyle":"0","bdsize":"16"},"share":{}};with(document)0[(getelementsbytagname('head')[0]||body).appendchild(createelement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new date()/36e5)];</script>
阅读(5) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
如何在R中高效安装ropls及其依赖包 本文详细介绍了在R语言中高效安装ropls包及其依赖的完整流程。作为Bioconductor生物信息学分析包,ropls的安装需通过BiocManager管理器进行。文章提供了标准安装步骤、跨系统避坑指南及安装后验证方法,帮助用户解决R版本、编译环境和网络镜像等常见问题,确保代谢组学数据分析工具顺利部署。 阅读详情

相关推荐

无刷电机控制基础(2)——有感和无感驱动、调速

上一篇文章我们讲了一些无刷电机的基础知识,包括无刷电机的内部结构,驱动原理等,我们知道了只需要按照转子的当前位置,来按顺序给定子线圈通电,就能让电机转动起来。但是,上一篇中我们跳过了一个关键步骤,就是如何检测转子的位置。本篇我们就讲讲常用的位置检测方法,以及引出的一些相关问题。我们知道,获取磁铁的位置可以用霍尔传感器,无刷电机的转子就是永磁体,因此只要在合适的位置安装霍尔传感器,就能知道转子的旋转位置。在无刷电机中,一般用3个开关型霍尔器件就能检测转子的位置。

小白白学电子 2万+

为什么一般用left+(right-left)/2而不是(right+left)/2

left+(right-left)/2和(right+left)/2

lconqure的博客 1040

用AI+Playwright实现零代码UI自动化测试:以登录页面为例的实战指南

本文详细介绍了如何利用AI与Playwright结合实现零代码UI自动化测试,特别以登录页面为例进行实战演示。通过自然语言描述生成测试脚本,大幅降低技术门槛,提升测试效率,并支持跨浏览器验证。适合非技术人员快速上手专业级自动化测试。

weixin_28842269的博客 402

经典算法之折半查找(BinarySearch)

算法 三分学,七分练,每天进步一点点。

小曾同学的博客 4805

Cadence IC 618实战:从与非门到环形振荡器的完整版图设计流程(含DRC/LVS避坑点)

本文详细介绍了使用Cadence IC 618进行从与非门到环形振荡器的完整版图设计流程,包括环境准备、基础设计规范、层次化设计、DRC/LVS验证及后仿真优化。特别提供了实战中的避坑技巧和优化建议,帮助工程师高效完成集成电路设计任务。

weixin_26886855的博客 405

FIddler+Proxifer 实现PC客户端抓包详细教程

FIddler+Proxifer 实现PC客户端抓包详细教程

森明帮大于黑虎帮的博客 1万+

二分查找算法

二分查找也常被称为二分法或者折半查找,每次查找时通过将待查找区间分成两部分并只取 一部分继续查找,将查找的复杂度大大减少。对于一个长度为 O(n) 的数组,二分查找的时间复 杂度为 O(log n)。举例来说,给定一个排好序的数组 {3,4,5,6,7},我们希望查找 4 在不在这个数组内。第一次 折半时考虑中位数 5,因为 5 大于 4, 所以如果 4 存在于这个数组,那么其必定存在于 5 左边这一 半。于是我们的查找区间变成了 {3,4,5}。

lclchong的博客 6195

人形机器人骨骼材料选型实战:从铝合金到碳纤维的5种方案对比

本文深入探讨人形机器人骨骼材料的选型策略,对比铝合金、镁合金、钛合金、碳纤维复合材料及3D打印材料等5种方案的性能优劣。通过建立强度-重量比、疲劳寿命等核心评价维度,结合具体应用场景,提供科学的材料决策方法论,助力开发者优化机器人结构设计,实现性能与成本的平衡。

weixin_29199873的博客 440

二分查找【多种方法+图解】

二分查找

Jambo!的博客 6061

Pytorch入门实战(2)-使用BP神经网络实现MNIST手写数字识别

上一篇:Pytorch入门实战(1) - 实现线性回归 涉及知识点 Pytorch nn.Module的基本使用 Pytorch nn.Linear的基本用法 PytorchVision Transforms的基本使用 Pytorch中DataLoader的基本用法 Pytorch详解NLLLoss和CrossEntropyLoss 如何确定神经网络的层数和隐藏层神经元数量 本文内容 本文将会使用BP神经网络(就是最普通的神经网络)实现一个MNIST手写数据集的实现。话不多说,直接开始。 首先先导入需要的包

iioSnail的博客 6617

请尽可能地详细说明一个VLA项目的立项训练到落地的全流程

一个机器人VLA项目的全流程是一个复杂的系统工程,它深度融合了机器人学 (Robotics)计算机视觉 (CV)和自然语言处理 (NLP)。其核心挑战在于高质量数据的获取和从仿真到现实的有效迁移。与纯粹的软件AI项目相比,它增加了硬件、物理交互和安全性的维度,但其最终能让AI走出虚拟世界、在物理世界中产生实际价值,这也是其巨大的魅力所在。

具身机器人和通用AI 303

【LeetCode刷题笔记/LeetCode704】二分查找left+(right-left)/2

二分查找使用条件:数组有序且元素无重复 二分查找经常用到left+(right-left)/2 代替mid = (left + right) / 2 原因就是left+right很容易超过int范围,导致mid = (left + right) / 2 容易溢出,而==mid = left + (right - left) / 2 ==不容易溢出,所以写二分时要用mid = left + (right - left) / 2。 题目:LeetCode704.二分查找 区间:[left,right]下: i

柠檬鱼的博客 688

GEE土地分类:土地分类精度评定和分类后影像进行(Kmeans,Gmeans,SNIC (Simple Non-Iterative Clustering)聚类分析和滤波(focal_mode)分析

使用聚类分析和滤波分析来进一步处理土地分类后的影像数据。聚类分析可以帮助您识别影像中的相似区域。您可以使用聚类算法,如K均值聚类或层次聚类,将像素分组到具有相似像素值的群集中。这可以帮助您更好地理解图像中的空间模式和结构,并可能揭示有用的信息。滤波分析可以帮助您平滑图像并去除噪声。常见的滤波器包括中值滤波器和高斯滤波器。这些滤波器可以帮助您消除图像中的随机变化,并使其更易于解释和分析。

此星光明博客 2516

从二分查找算法来看如何写出正确的程序

平时我们写程序的时候,总是莫名其妙的出现Bug,一鼓作气的写完一个接口后,经常被队友喷「你怎么一回事?结果与预期不一致啊」 老脸一红,然后一个人藏在角落调试半天,才发现原来是某一个边界条件没处理好,导致Bug重重,今天我们从二分查找算法,来聊聊如何写出正确的程序 像我们熟知的二分查找算法,在1946年就被提出来了,但是到了1962年才出现了完全没有Bug的二分查找法 二分查找法的思想并不复杂,我...

AdolphKevin的博客 505

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

怎么将算法改成程序_从二分查找算法来看如何写出正确的程序

从二分查找算法来看如何写出正确的程序平时我们写程序的时候,总是莫名其妙的出现Bug,一鼓作气的写完一个接口后,经常被队友喷「你怎么一回事?结果与预期不一致啊」老脸一红,然后一个人藏在角落调试半天,才发现原来是某一个边界条件没处理好,导致Bug重重,今天我们从二分查找算法,来聊聊如何写出正确的程序像我们熟知的二分查找算法,在1946年就被提出来了,但是到了1962年才出现了完全没有Bug的二分查找法...

weixin_39705435的博客 205

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

您能写出一个正确的二分查找算法吗?

二分查找很容易吧? 初来乍到的二分查找 public static int binarySearchBad(int arr[],int value) { int low=0,high=arr.length-1; int middle; while(low<=high) { middle=low+(hi...

weixin_30247781的博客 398

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

浅谈如何写出一个正确的二分查找算法

前言 二分在算法竞赛方面是一个非常重要的算法, 虽然算法思想与实现都是比较简单易懂的, 但是真正的代码实现,往往都是十分代码九份有BUG. 博主在考研复习中又重新学习了这个两年前貌似都掌握的算法, 在这里写下这个文章作为学习笔记, 也希望可以帮助到更多的人写出可以在更多的场景下无BUG的二分. C++的内置函数-求下界 lowerbound() 与 upperbound() 这两个函数的返回值...

Yishui_lovely 702

3-1 从二分查找法看如何写出正确的程序

如何写出正确的程序 设定“循环不变量”,即我们寻找的数据索引一定在该范围中:[l .. r]。 数组中可查找的数据的索引范围为:[0, n-1],前闭后闭。 设置循环结束条件:当 l <= r,区间 [l ... r] 依然是有效的,数组中仅包含一个元素 设置返回条件: arr[mid] == target,返回mid arr[mid] > target,target在 [mid+1 ... r]中 arr[mid] <target,target在 [l ....

SIONCIOSC的博客 286

二分查找的三个版本,据说90%的计算机专家不能在2小时内写出完全正确的二分搜索算法。

折半查找法也称为二分查找法,它充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用O(log n)完成搜索任务。 【基本思想】 将n个元素分成个数大致相同的两半,取a[n/2]与欲查找的x作比较,如果x=a[n/2]则找到x,算法终止。如果xa[n/2],则我们只要在数组a的右半部继续搜索x。 二分搜索法的应用极其广泛,而且它的思想易于理解。第一个二分搜索算法早在1946

To lose to pursue. 1820

二分查找算法的细节剖析

原文:https://www.cnblogs.com/kyoner/p/11080078.html 我周围的人几乎都认为二分查找很简单,但事实真的如此吗?二分查找真的很简单吗?并不简单。看看 Knuth 大佬(发明 KMP 算法的那位)怎么说的: Although the basic idea of binary search is comparatively straightforward, the details can be surprisingly tricky… 这句话可以这样理解:思路很简单

JackComeOn的博客 437

漫谈二分查找-Binary Search (转)

http://duanple.blog.163.com/blog/static/709717672009049528185/  (用vim把程序缩进了一下,方便看) 历史上,Knuth在其>一书的第6.2.1节指出:尽管第一个二分搜索算法于1946年就出现,然而第一个完全正确的二分搜索算法直到1962年才出现。 而不经仔细斟酌而写出的一个二分查找经常遭遇off by one或者无限循

Pegasus (http://ningning.today) 1138

二分查找算法的三个注意点

如何写出正确的二分查找算法? 二分查找算法很经典,但不少人一看就会一写就废(包括我),关键问题出现在对以下三个细节没有理解正确。 注意点1:左闭右闭还是左闭右开? 给定数组长度n,high到底等于n还是n-1? 两种写法都是可以的,但选择其中一种后,会衍生出两种不同版本的二分查找写法,具体的我们在下面推导。 注意点2:等于还是小于等于? 假设选择左闭右闭,那么 low = high 就是有意义的,怎么理解?假设数组长度为 1,你在 while 条件里写了 low < high,则当 low = hig

qq_35800932的博客 377

算法学习笔记:labuladong--二分查找

**核心问题:**二分查找并不简单,Knuth 大佬(发明 KMP 算法的那位)都说二分查找:思路很简单,细节是魔鬼。很多人喜欢拿整型溢出的 bug 说事儿,但是二分查找真正的坑根本就不是那个细节问题,而是在于到底要给 mid 加一还是减一,while 里到底用 <= 还是 <。 你要是没有正确理解这些细节,写二分肯定就是玄学编程,有没有 bug 只能靠菩萨保佑。我特意写了一首诗来歌颂该算法,概括本文的主要内容,建议保存: 零、二分查找框架: int binarySearch(int[] nu

qq_41306849的博客 829

二分查找实现(Jon Bentley:90%程序员无法正确实现)

引言     Jon Bentley:90%以上的程序员无法正确无误的写出二分查找代码。也许很多人都早已听说过这句话,但我还是想引用《编程珠玑》上的如下几段文字:  “二分查找可以解决(预排序数组的查找)问题:只要数组中包含T(即要查找的值),那么通过不断缩小包含T的范围,最终就可以找到它。一开始,范围覆盖整个数组。将数组的中间项与T进行比较,可以排除一半元素,范围缩小一半。就这样反复

u012512762的专栏 797

重温二分查找算法(r4笔记第66天)

二分查找在学习算法的时候会涉及到,算是一个基本的分治思想,对于算法的实现大家也都是很熟悉的,但是这个时候真会犯眼高手低的毛病。不信你自己试试,看你能够在段时间内写出可运行...

杨建荣的学习笔记 191

小班讨论-二分查找

二分查找 相关资料 思路很简单,细节是魔鬼。 本文就来探究几个最常用的二分查找场景:寻找一个数、寻找左侧边界、寻找右侧边界。 而且,我们就是要深入细节, 比如while循环中的不等号是否应该带等号, mid 是否应该加一等等。 分析这些细节的差异以及出现这些差异的原因 保证你能灵活准确地写出正确的二分查找算法。 一、二分查找的框架 int binarySearch(int[] nums, int target) { int left = 0, right = ...;

m0_56147044的博客 109
上一篇: Leetcode---Implement strStr()
下一篇: Leetcode---Symmetric Tree
我把葡萄酿成酒
博客等级 码龄12年 275粉丝 198原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值