3.优化算法之二分查找1

二分查找简介

1.特点

最简单最恶心,细节最多,最容易写出死循环的算法

2.学习中的侧重点

1)算法原理

数组有序的情况

2) 模板

不要死记硬背 ->理解之后再记忆

1.朴素的二分模板
2.查找左边界的二分模板
3.查找右边界的二分模板

//后面两个是万能模板,细节很多

1.二分查找 

1)题目描述

2)算法原理

二分查找

根据规律能把数组分为两部分,可以用二分查找(选择中间这个点的时间复杂度是最小的)

 

class Solution {public int search(int[] nums, int target) {int left=0,right=nums.length-1;while(left<=right){int mid=(left+right)/2;if(nums[mid]==target){return mid;}else if(nums[mid]>target){right=mid-1;}else{left=mid+1;}}return -1;}
}

我们在计算mid的时候要考虑数字的溢出

int mid=left+(right-left)/2; 

class Solution {public int search(int[] nums, int target) {int left=0,right=nums.length-1;while(left<=right){// int mid=(left+right)/2;int mid=left+(right-left)/2;//防止溢出if(nums[mid]==target){return mid;}else if(nums[mid]>target){right=mid-1;}else{left=mid+1;}}return -1;}
}

朴素版本的时候 :

mid=left+(right-left+1)/2;==mid=left+(right-left)/2;

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

1)题目描述

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]

你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

示例 2:

输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]

示例 3:

输入:nums = [], target = 0
输出:[-1,-1]

2)算法原理

仍然是用朴素二分

class Solution {public int[] searchRange(int[] nums, int target) {//首先进行特殊情况的处理if(nums.length==0){return new int[]{-1,-1};}if(nums.length==1){return nums[0]==target?new int[]{0,0}:new int[]{-1,-1};}int l=0,r=nums.length-1;while(l<=r){int mid=(l+r)/2;if(nums[mid]==target){l=r=mid;//找到左标记while(l>=1&&nums[l-1]==target){l--;}//找到右标记while(r<nums.length-1&&nums[r+1]==target){r++;}return new int[]{l,r};}if(nums[mid]>target){r=mid-1;}else{l=mid+1;}}return new int[]{-1,-1};}
}

但是如果数组全是3的话,我们的时间复杂度又会降成O(N)

class Solution {public int[] searchRange(int[] nums, int target) {int[] ret=new int[2];ret[0]=ret[1]=-1;//1.处理边界条件int n=nums.length;if(n==0){return ret;}//2.二分左端点int left=0,right=n-1;while(left<right){int mid=left+(right-left)/2;if(nums[mid]<target){left=mid+1;}else{right=mid;}}//判断是否有结果if(nums[left]!=target){return ret;}else{ret[0]=left;}//2.二分右端点left=0;right=n-1;while(left<right){int mid=left+(right-left+1)/2;if(nums[mid]>target){right=mid-1;}else{left=mid;}}//判断是否有结果if(nums[right]!=target){return ret;}else{ret[1]=right;}return ret;}
}

 

3.x的平方根 

69. x 的平方根 - 力扣(LeetCode)

1)题目描述

给你一个非负整数 x ,计算并返回 x 的 算术平方根 。

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。

示例 1:

输入:x = 4
输出:2

示例 2:

输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。

2)算法原理

 

class Solution {public int mySqrt(int x) {if(x<1){return 0;}long left=0,right=x;while(left<right){long mid=left+(right-left+1)/2;//防止溢出if(mid*mid>x){right=mid-1;}else{left=mid;}}return (int)left;}
}

4.搜索插入位置 

1)题目描述

35. 搜索插入位置 - 力扣(LeetCode)

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

2)算法原理

class Solution {public int searchInsert(int[] nums, int target) {//首先进行特殊情况的处理if(nums.length==0){return 0;}int left=0,right=nums.length-1;while(left<right){int mid=left+(right-left)/2;if(nums[mid]<target){left=mid+1;}else{right=mid;}}//二分法只能处理在数组中间的情况,我们是在数组中找结果//所以需要特判if(nums[left]<target){return left+1;}return left;}
}

left和right相遇了,想写谁写谁 

5.山脉数组的峰顶索引

852. 山脉数组的峰顶索引 - 力扣(LeetCode)

1)题目描述

给定一个长度为 n 的整数 山脉 数组 arr ,其中的值递增到一个 峰值元素 然后递减。

返回峰值元素的下标。

你必须设计并实现时间复杂度为 O(log(n)) 的解决方案。

示例 1:

输入:arr = [0,1,0]
输出:1

示例 2:

输入:arr = [0,2,1,0]
输出:1

示例 3:

输入:arr = [0,10,5,2]
输出:1

2)算法原理

class Solution {public int peakIndexInMountainArray(int[] arr) {int left=0,right=arr.length;while(left<right){int mid=left+(right-left+1)/2;if(arr[mid]>arr[mid-1]){//此时说明在左半边left=mid;}else if(arr[mid]<arr[mid-1]){//说明在右侧right=mid-1;}}return left;}
}

 6.寻找峰值

寻找峰值

1)题目描述

峰值元素是指其值严格大于左右相邻值的元素。

给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。

你可以假设 nums[-1] = nums[n] = -∞ 。

你必须实现时间复杂度为 O(log n) 的算法来解决此问题。

2)算法原理

 

 

class Solution {public int findPeakElement(int[] nums) {int left=0,right=nums.length-1;while(left<right){int mid=left+(right-left)/2;if(nums[mid]<nums[mid+1]){left=mid+1;}else if(nums[mid]>nums[mid+1]){right=mid;}}return left;}
}

 7.寻找排序数组的最小值

1)题目描述

153. 寻找旋转排序数组中的最小值 - 力扣(LeetCode)

已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:

  • 若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
  • 若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]

注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。

给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

输入:nums = [3,4,5,1,2]
输出:1
解释:原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。

示例 2:

输入:nums = [4,5,6,7,0,1,2]
输出:0
解释:原数组为 [0,1,2,4,5,6,7] ,旋转 3 次得到输入数组。

示例 3:

输入:nums = [11,13,15,17]
输出:11
解释:原数组为 [11,13,15,17] ,旋转 4 次得到输入数组。

提示:

  • n == nums.length
  • 1 <= n <= 5000
  • -5000 <= nums[i] <= 5000
  • nums 中的所有整数 互不相同
  • nums 原来是一个升序排序的数组,并进行了 1 至 n 次旋转

2)算法原理

 

class Solution {public int findMin(int[] nums) {int n = nums.length - 1;int left = 0, right = n;while (left < right) {int mid=left+(right-left)/2;if(nums[mid]>nums[n]){left=mid+1;}else if(nums[mid]<=nums[n]){right=mid;}}return nums[left];}
}

 8.0~n-1中缺失的数字

1)题目描述

LCR 173. 点名 - 力扣(LeetCode)

某班级 n 位同学的学号为 0 ~ n-1。点名结果记录于升序数组 records。假定仅有一位同学缺席,请返回他的学号。

示例 1:

输入: records = [0,1,2,3,5]
输出: 4

示例 2:

输入: records = [0, 1, 2, 3, 4, 5, 6, 8]
输出: 7

提示:

1 <= records.length <= 10000

2)算法原理 

class Solution {public int takeAttendance(int[] records) {int left=0,right=records.length-1;//1.处理特殊情况if(records[right]==right){return right+1;}while(left<right){int mid=left+(right-left)/2;if(records[mid]==mid){left=mid+1;}else{right=mid;}}return left;}
}

 

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

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

相关文章

24年了 直播带货的未来如何?

32 个国家在取消电商&#xff0c; 那我国的电商呢&#xff0c;首先电商是不会被取缔的。直播电商会被严格的控制&#xff0c;比如有一家饼店&#xff0c;它线下的销售是 3000 万&#xff0c;线上抖音的销售是 5, 000 万。 这一类型小而精又专业的品牌企业&#xff0c;未来在抖…

Sensei for Mac:一键清理,系统如新!

Sensei for Mac是一款高效且易于使用的系统优化清理工具。它能够深入Mac系统内部&#xff0c;智能识别并清理无用的缓存文件、临时文件、垃圾邮件等&#xff0c;从而释放磁盘空间&#xff0c;提升系统性能。无论是日常使用还是长时间工作后&#xff0c;Sensei都能帮助你的Mac恢…

鸿蒙 HarmonyOS NEXT星河版APP应用开发阶段三-热门组件使用及案例

一、样式和结果重用 介绍 /* Extend:扩展组件&#xff08;样式、事件&#xff09; Styles: 抽取通用数据、事件 Builder:自定义构建函数&#xff08;结构、样式、事件&#xff09; */Extend /* 作用&#xff1a;扩展组件&#xff08;样式、事件&#xff09; 场景&#xff1a;…

封装图片占位图组件

<laze-image class="image" :url="item.image" :game_name="item.game_name" :placeholder="require(@/static/images/common/placeholder.png)"></laze-image> 1.通过调用组件实现 先加载预览图片,再加载真实的图片 2…

中国杀出全球首个烹饪大模型

什么&#xff1f;烹饪也有大模型&#xff1f;&#xff01; 没有听错&#xff0c;这就是国产厨电龙头老板电器最新发布——“食神”大模型。 数十亿级行业数据&#xff0c;数千万级知识图谱加持&#xff0c;据称还是全球首个。 它能为每个人提供个性化量身定制的解决方案&…

TikTok短视频矩阵系统

随着数字化时代的到来&#xff0c;短视频已成为人们获取信息、娱乐消遣的重要渠道。TikTok&#xff0c;作为全球最受欢迎的短视频平台之一&#xff0c;其背后的短视频矩阵系统是支撑其成功的关键因素。本文将深入探讨TikTok短视频矩阵系统的构成、功能以及它在新媒体时代中的影…

什么领夹麦的音质最好又降噪?揭秘多款降噪出色的无线领夹麦克风

随着短视频的兴起&#xff0c;将视频拍摄方面的外设推到了风口浪尖上&#xff0c;麦克风作为视频拍摄或者现场直播使用的主要拾音工具&#xff0c;自然成为了大家非常关注的一个摄影外设工具&#xff0c;毕竟一款好的拾音工具能够给视频创作者或者直播博主带来更好的使用体验。…

汇川H5u小型PLC作modbusRTU从站设置及测试

目录 新建工程COM通讯参数配置协议选择协议配置 查看手册Modbus地址对应关系仿真测试 新建工程 新建一个H5U工程&#xff0c;不使用临时工程 系列选择H5U即可 COM通讯参数配置 协议选择 选择ModbusRTU从站 协议配置 端口号默认不可选择 波特率这里使用9600 数据长度&…

Nuxt3 实战 (十二):SEO 搜索引擎优化指南

添加 favicon 图标和 TDK&#xff08;标题、描述、关键词&#xff09; nuxt.config.ts 添加配置&#xff1a; export default defineNuxtConfig({app: {title:Dream Site,meta: [{ name: keywords, content: Nuxt.js,导航,网站 },{ name: description, content: 致力于打造程…

CCF秀湖会议:“第五存储架构”引发关注

近日&#xff0c;中国计算机学会第十三期CCF秀湖会议在苏州CCF业务总部&学术交流中心正式召开。本次会议就“新应用与硬件驱动下的存储技术创新”主题进行深入交流和探讨。中国工程院院士、清华大学郑纬民教授&#xff0c;华中科技大学金海教授&#xff0c;清华大学舒继武教…

计算机毕业设计Thinkphp/Laravel+vue高校图书馆借阅系统_i0521

图书馆借阅系统&#xff0c;主要的模块包括首页、个人中心、会员管理、会员等级管理、图书分类管理、图书信息管理、图书借阅管理、借阅服务评价管理、超时费用管理、留言板管理、系统管理等功能。系统中管理员主要是为了安全有效地存储和管理各类信息&#xff0c;还可以对系统…

浅学JVM

一、基本概念 目录 一、基本概念 二、JVM 运行时内存 1、新生代 1.1 Eden 区 1.2. ServivorFrom 1.3. ServivorTo 1.4 MinorGC 的过程 &#xff08;复制- >清空- >互换&#xff09; 1.4.1&#xff1a;eden 、servicorFrom 复制到ServicorTo&#xff0c;年龄1 …

力扣每日一题 特别的排列 DFS 记忆化搜索 位运算 状态压缩DP

Problem: 2741. 特别的排列 &#x1f468;‍&#x1f3eb; 参考题解 &#x1f37b; 暴搜 ⏰ 时间复杂度&#xff1a; O ( N ) O(N) O(N) class Solution {public int specialPerm(int[] nums) {boolean[] visited new boolean[nums.length];return dfs(nums, 0, -1, visit…

目标检测系列(二)yolov1的全面讲解

目录 1、网络结构 2、检测原理 3、制作训练正样本方法 4、损失函数 5、前向推理 6、模型缺限 YOLO的全称是you only look once&#xff0c;指只需要浏览一次就可以识别出图中的物体的类别和位置。YOLO被称为Region-free方法&#xff0c;相比于Region-based方法&#xff0…

AI已经火了一年了,真正属于普通人的机会在哪里?

对普通人来说&#xff0c;AI的机会在哪里&#xff1f; 这是过去一年来&#xff0c;我收到过最多的问题 在这篇文章里&#xff0c;我会把我目前对AI的理解阐述出来&#xff0c;分享3个普通人能够把握的方向 讲清楚在现在这个时间节点&#xff0c;当我们在说搞AI的时候&#x…

RAG应用要如何吃到大模型长上下文的红利?-LongRAG

去年底的时候&#xff0c;笔者写过&#xff0c;与其在RAG系统上雕花&#xff0c;可以重新思考一下&#xff0c;自己的业务场景是否非RAG不可吗&#xff1f;随着去年大模型的蓬勃发展&#xff0c;长度外推、更长的上下文模型&#xff0c;更厉害的中文底座大模型&#xff0c;都可…

RabbitMq camel

真实的项目如果 交换器/ 队列很多 建议在管理页面新建exchange / queue/ rootingKey /vhost, 而不要写死在springboot项目里 camel按rooting key发送消息: 最推荐 .to("rabbitmq:sino.nannan?routingKeysino.key&skipExchangeDeclaretrue&skipQueueDeclaretru…

Python 挖坑式填充Excel模板内容(包括页眉/SheetName/logo)

纵览 Python处理Excel的方式--解压缩方式1、导包2、对模板文件进行解压缩3、对解压缩后文件层级进行介绍4、准备需要载入的数据5、模板挖坑6、运行替换代码7、压缩文件8、生成文件9、完成代码10、可能遇到的问题 结语 Python处理Excel的方式–解压缩方式 在处理Excel中过程中&…

《人人都是产品经理》:项目的坎坷一生

《人人都是产品经理》&#xff1a;项目的坎坷一生 产品VS项目产品经理和项目经理 一切项目从kick off 开始工作量预估Kick Off的大致也就15分钟 写文档咯UML图用例文档UCdemo也得做 需求活在项目中bug等级有多高bug流转过程 以终为始 产品VS项目 项目定义&#xff1a;是只会进…

怎么压缩pdf文件大小,如何压缩pdf文件大小

pdf文件怎么压缩&#xff1f;在当下这个信息爆炸的时代&#xff0c;无论是在工作场所还是校园中&#xff0c;我们经常会面临需要处理大文件的情况&#xff0c;而PDF格式作为一种保留文档结构和布局完整性的理想选择&#xff0c;有时候pdf文件太大&#xff0c;因此&#xff0c;对…