二分法问题

news2024/11/24 10:46:48

 日升时奋斗,日落时自省

目录

1、二分法

2、二分法问题

 2.1 、在排序数组中查找元素的第一个和最后一个位置

2.2、搜索插入位置

2.3、山脉数组的峰顶索引

2.4、0-n-1中缺失的数字


1、二分法

二分法是比较简单的一种查找算法,但是效率很高,很多友友们也会觉得二分法没有什么好说的,就是取中,对比,位置变化,其实大体上也就是这么三个

注:二分法适用条件 有二段性 ,其实就是有规律的分段,排序就是其中常见的一种

第一类普通二分法:

代码:

    public static int search(int[] nums,int target){
        //二分范围就是 具有二段性的范围 这里是一个排序好的数组具有 二段性
        //left就是左边界 right 就是右边界
        int left = 0,right =nums.length-1;
        //判断条件 为什么会有等于
        //因为这里是为了可以找到 我们要的 并且存在的下标
        //等于的情况就是我们需要找的 
        while (left<=right){
            int mid = left + (right - left) /2;
            //如果目标值大于中间值  left给小了
            //target的存在位置一定大于mid left是当前区间最小位置 更新这里left的位置就是mid+1
            if(target>nums[mid]){
                left=mid+1;
            //如果目标值小于中间值  right给大了
            //target的存在位置一定小于mid right是当前区间最大位置 更新这里right的位置就是mid-1
            }else if(target<nums[mid]){
                right=mid-1;
            }else {
                return mid;
            }
        }
        return -1;
    }

第二种就是找左边界值(二分法):

有没有见过1,2,3,4,4,4,4,5,7,8这种需要你找到当前元素中找到最左边4的位置

这就是特殊类型的二分法了

注:建议先看代码在看图

图示:

代码:

    public static int search(int[] nums,int target){
        int left = 0, right = nums.length - 1;
        //不在是为了找到 对应的值 而是一个极端的下标 
        //所以没有等号
        while(left<right){
            //寻找左端点   (right-left)/2 是靠左的
            int mid = left + (right - left)/2;
            if(nums[mid]<target){
                //目标值大于 中间值 说明left偏小
                left=mid+1;
            }else {
                //right不同 如果target小等于 right边小到 mid 位置
                //为啥呢 因为 target==nums[mid] 那此时极端下标就是mid
                //right等于相等情况的下标 mid
                right=mid;
            }
        }
        //left==right 此时  所以返回right也可以  
        return left;
    }

第二种就是找右边界值(二分法):

有没有见过1,2,3,4,4,4,4,5,7,8这种需要你找到当前元素中找到最右边4的位置

这就是特殊类型的二分法了

注:方法大体相同

mid = left + (right - left + 1)/2 表示取值靠右

剩下的就是条件了

图示:

代码:

public static int search(int[] nums,int target){
        int left = 0, right = nums.length - 1;
        //不在是为了找到 对应的值 而是一个极端的下标
        //所以没有等号
        while(left<right){
            //寻找左端点   (right-left+1)/2 是靠右的
            int mid = left + (right - left+1)/2;
            if(nums[mid]>target){
                //目标值小于 中间值 说明right偏大
                right=mid-1;
            }else {
                //right不同 如果target大等于 left边小   到mid 位置
                //为啥呢 因为 target==nums[mid] 那此时极端下标就是mid
                //left等于相等情况的下标 mid
                left=mid;
            }
        }
        //left==right 此时  所以返回right也可以
        return left;
    }

2、二分法问题

 2.1 、在排序数组中查找元素的第一个和最后一个位置

题目来源:. - 力扣(LeetCode)

其实就是把两种特殊二分进行使用 找左值 也 找右值

代码:

    public int[] searchRange(int[] nums, int target) {
        //题目说了要两个 下标 咱们建立一个数组来放置
        int[] ret=new int[2];
        //例题已经给了 要求为空 数组返回 -1 -1
        if(nums.length==0){
            return new int[]{-1,-1};
        }
        //二分两边的位置  
        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;
            }
        }
        //此时进行一次判断 如果left没有找到也就是没有目标值
        if(nums[left]!=target){
            //不存在直接返回 -1 -1
            return new int[]{-1,-1};
        }
        //记录一下
        ret[0]=left;
        //其实这里 可以不用在初始化的 
        //为了方便友友们看懂
        left=0;right=nums.length-1;
        //寻找右端点
        while(left<right){
            //靠右条件
            int mid =left+(right-left+1)/2;
            if(nums[mid]>target){
                right=mid-1;
            }else if(nums[mid]<=target){
                left=mid;
            }
        }
        //记录右下标
        ret[1]=left;
        return ret;
    }

注:不要害怕长,整个代码都是前面的代码构成的,算是套模板

2.2、搜索插入位置

题目来源:. - 力扣(LeetCode)

在一个数组中找目标元素,如果存在返回下标,如果不存在找到排序好的下标

代码:

    public int searchInsert(int[] nums, int target) {
        int left=0,right=nums.length-1;
        while(left<right){
            //找右值
            int mid=left+ (right-left+1)/2;
            if(nums[mid]<=target){
                left=mid;
            }else{
                right=mid-1;
            }
        }
        //如果目标值大于left 说明没有找到 
        //此时left+1就是排序好的下标
        if(nums[left]<target){
            return left+1;
        }else {
            //相等就是找到了
            return left;
        }
    }

2.3、山脉数组的峰顶索引

题目来源:. - 力扣(LeetCode)

图示:

代码:

    public int peakIndexInMountainArray(int[] arr) {
        int left=0,right=arr.length-2;
        while(left<right){
            //靠右取条件
            int mid=left+(right-left+1)/2;
            //数组遵循大体就是   /\
            //               /  \
            //              /    \   在一定区间内有二段性  
            //所以每次目标值都是mid-1的位置
            if(arr[mid]>arr[mid-1])left=mid;
            //如果小于说明right 太大了
            else right=mid-1;
        }
        return left;
    }

2.4、0-n-1中缺失的数字

这个暂时在leetcode上没有找到合适的,友友们作为练手,leetcode上有些题有些变动,原来是有的,现在可以能题目名字变了

1  2   3   4   5  6  8  9  10 少了个7

注:其实这里普通二分法也能解决问题,这里没有用普通二分,使用找左端点的二分法

代码:

    public static void main(String[] args) {
        int[] nums={0,1,2,3,4,5,6,7,8,9,10};
        System.out.println(missingNumber(nums));
    }
    public static int missingNumber(int[] nums){
        int left = 0, right = nums.length-1;
        while(left<right){
            //靠左条件
            int mid = left + (right-left)/2;
            if(nums[mid]==mid){
                left=mid+1;
            }else {
                right=mid;
            }
        }
        //如果找到了 小的了 说明缺下一个位置 left+1 
        return nums[left]==left?left+1:left;
    }

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

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

相关文章

掌握Node Version Manager(nvm):跨平台Node.js版本管理

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

瀑布流组件(vue2)

文档连接&#xff1a;clz 加载状态、行数 可以自行控制&#xff0c;目前只支持vue2 实现效果&#xff1a;

【TDSQL】TCPMSS最大数据分段大小值不合理导致JAVA程序连接数据库异常案例

欢迎关注“数据库运维之道”公众号&#xff0c;一起学习数据库技术! TDSQL核心架构原理解析下载链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;vat5 DTC2024 数据技术嘉年华&#xff08;演讲资料下载&#xff09;DTC2024 数据技术嘉年华&#xff08;演讲资料下载…

生成人工智能体:人类行为的交互式模拟论文与源码架构解析(5)——可控评估端到端评估

最后完结篇,文末有测试中发现的有趣现象,并附上了相关资料链接~ 5.可控评估 分两个阶段评估生成代理。我们从一个更加严格控制的评估开始,单独评估代理的响应,以了解它们是否在狭义上定义的上下文中产生可信的行为。然后,在我们对代理社区进行为期两天的端到端分析中,我…

决策树分类器(保姆级教学) 定义+特性+原理及公式+鸢尾花分类经典问题示例(完整Python代码带详细注释、保姆级分部代码解释及结果说明、决策树可视化及解释)

文章目录 引言定义特性基本原理和公式理解信息增益&#xff08;ID3算法&#xff09;熵的定义条件熵信息增益的计算 基尼不纯度&#xff08;CART算法&#xff09;基尼不纯度的定义基尼不纯度的计算例子 实现步骤解决鸢尾花分类问题&#xff08;机器学习入门中的经典案例Python代…

传感器融合 | 适用于自动驾驶场景的激光雷达传感器融合项目_将激光雷达的高分辨率成像+测量物体速度的能力相结合

项目应用场景 面向自动驾驶场景的激光雷达传感器融合&#xff0c;将激光雷达的高分辨率成像测量物体速度的能力相结合&#xff0c;项目是一个从多个传感器获取数据并将其组合起来的过程&#xff0c;可以更加好地进行环境感知。项目支持 ubuntu、mac 和 windows 平台。 项目效果…

在系统中设定延迟任务和定时任务

useradd easylee //设置名为easylee的新用户 passwd easylee //更改密码为easylee&#xff0c;输入两次即可 将root和easylee加入白名单&#xff0c;使系统中只有root用户和easylee用户可以执行延迟任务的设置。 建立任务并给权限 定时任务

vue 实现实时搜索文档关键字并高亮显示

最近接到的一个新需求&#xff1a;实时搜索文档关键字并高亮显示&#xff0c;听起来好难的样子&#xff0c;仔细分析起来其实也蛮简单的。 实现思路 通过 input 实现关键字的输入&#xff0c;监听关键字的变化&#xff0c;用正则表达式来匹配关键字&#xff0c;然后给关键字添…

视觉信息保真度VIF算法详细介绍

来源 算法核心思想来源该篇论文A VISUAL INFORMATION FIDELITY APPROACH TO VIDEO QUALITY ASSESSMENT;是2005年的一篇高引用文章; 是一种全参考的视频图像评价算法;在奈飞开源的视频质量评价工具vmaf中将其作为一个判断维度,具体关于vmaf介绍可以参考视频质量评价工具vmaf…

一文学会时序约束

主时钟约束命令/生成时钟约束命令IO输入输出延迟约束命令及效果最大最小延迟命令及作用多周期路径怎么约束什么情况设置伪路径时钟组设置的三个选项 如果不了解时序分析可以先看下下面这篇文章&#xff1a; 数字IC/FPGA——时序分析 目录 1.时钟约束&#xff08;1&#xff09;…

SRIO系列-仿真测试

一、前言 前两篇已经讲述了SRIO协议的概况&#xff0c;以及xilinx SRIO IP核的使用方式&#xff0c;已经在搭建工程的过程中时钟和复位的注意事项。 二、设计框图 整个框图也是按照之前的工程进行搭建&#xff0c;首先时SRIO_Channel&#xff0c;由SRIO IP核和时钟、复位模块…

【C++题解】1607. 两位数运算

问题&#xff1a;1607. 两位数运算 类型&#xff1a;基本运算、拆位求解 题目描述&#xff1a; 小丽在编程课上学会了拆位运算&#xff0c;她已经可以拆出一个两位整数的十位和个位了&#xff0c;她想知道这个整数的十位 / 个位的结果是多少&#xff0c;请编程帮她实现&#…

异地网络如何在线共享文件夹?

信息的传输和共享变得异常便利。而对于拥有异地办公或分布式团队的公司或组织来说&#xff0c;跨地域的文件共享变得尤为重要。在这个背景下&#xff0c;“异地网络在线共享文件夹”应运而生。 异地网络在线共享文件夹的意义 对于异地办公的团队来说&#xff0c;共享文件夹是一…

《Super Simple Skybox》天空盒 -- 创造绝美天空的神奇工具!限时免费!

《Super Simple Skybox》天空盒 -- 创造绝美天空的神奇工具&#xff01;限时免费&#xff01; 前言内容介绍资源特色动态&#xff0c;美丽的天空在几秒钟内即插即用 功能列表领取兑换码 前言 ^^在这个充满创意与想象的世界里&#xff0c;Unity 免费资源犹如一颗璀璨的明珠&…

信息系统项目管理师0055:优化和持续改进(4信息系统管理—4.1管理方法—4.1.5优化和持续改进)

点击查看专栏目录 文章目录 4.1.5优化和持续改进1.定义阶段2.度量阶段3.分析阶段4.改进/设计阶段5.控制/验证阶段4.1.5优化和持续改进 优化和持续改进是信息系统管理活动中的一个环节,良好的优化和持续改进管理活动能够有效保障信息系统的性能和可用性等,延长整体系统的有效使…

redis的数据结构报错

文章目录 redis的数据结构报错Redis使用LocalDateTime报错问题 redis的数据结构报错 Redis使用LocalDateTime报错问题 SpringBoot整合Redis时&#xff0c;使用LocalDate以下报错 org.springframework.data.redis.serializer.SerializationException: Could not read JSON: C…

统一SQL-支持cast函数

统一SQL介绍 https://www.light-pg.com/docs/LTSQL/current/index.html 源和目标 源数据库&#xff1a;Oracle 目标数据库&#xff1a;Postgresql&#xff0c;TDSQL-MySQL&#xff0c;达梦8&#xff0c;LightDB-Oracle 操作目标 在Oracle中&#xff0c;cast函数允许将一种…

CSS:filter(滤镜)属性

用途 可以用于img标签&#xff0c;div标签等 图像&#xff0c;背景&#xff0c;边框的调整 常用属性 1. 灰度 grayscale()&#xff0c;默认是0&#xff0c;100%就是黑白 2. blux 给图像设置高斯模糊的程度&#xff0c;radius值设定高斯模糊的程序&#xff0c;表示像素点…

android studio gradle 下载不下来的问题

有时候由于网络问题&#xff0c;会发现 android-studio 或 idea 下载不懂 gradle&#xff0c;可以修改 gradle-wrapper.properties 配置文件中的 distributionUrl 选项来解决这个问题。 distributionUrlhttps\://mirrors.cloud.tencent.com/gradle/gradle-5.1.1-all.zip 这个选…

遥感图像分割 | 基于一种类似UNet的Transformer算法实现遥感城市场景图像的语义分割_适用于卫星图像+航空图像+无人机图像

项目应用场景 面向遥感城市场景图像语义分割场景&#xff0c;项目采用类似 UNet 的 Transformer 深度学习算法来实现&#xff0c;项目适用于卫星图像、航空图像、无人机图像等。 项目效果 项目细节 > 具体参见项目 README.md (1) 安装依赖 conda create -n airs python3.8…