二分查找1

1. 二分查找(704)

题目描述:
在这里插入图片描述
算法原理:
暴力解法就是遍历数组来找到相应的元素,使用二分查找的解法就是每次在数组中选定一个元素来将数组划分为两部分,然后因为数组有序,所以通过大小关系舍弃一部分数组,最终不断重复这个过程完成查找,时间复杂度可以达到logN。
代码如下:

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

题目链接

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

题目描述:
在这里插入图片描述
朴素二分查找:
这题我们可以先使用朴素二分查找的方法取找到等于target的元素下标,此时再分别使用两个循环去比较左右两边元素是否与target相等,如果相等则分别向左和向右移动,最终返回对应的下标即可,这个过程很好理解。
代码如下:

class Solution {public int[] searchRange(int[] nums, int target) {int left = 0, right = nums.length - 1;int index1 = -1, index2 = -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 {index1 = mid;index2 = mid;while (index1 - 1 >= 0 && nums[index1] == nums[index1 - 1]) {index1--;}while (index2 + 1 < nums.length && nums[index2] == nums[index2 + 1]) {index2++;}break;}}return new int[] { index1, index2 };}
}

优化朴素二分查找:
首先我们去寻找target的左边界,为了便于理解我们给出图1,数组的元素可以分为两个部分,前半部分是小于target的元素,后一部分是大于等于target的部分。
图1
在这里插入图片描述
如图2,当我们的nums[mid]也就是x落入前半部分的时候,为了去接近target需要使得left=mid+1,当我们的x落入后半部分的时候,此时我们不能够使right=mid-1,因为如果说此时x是等于target的并且是左边的最后一个target,那么将right-1后面就直接再也找不到正确的target了。综上,如果x落入图1的第二段区间,那么就使得right=mid。很好理解的一点就是通过这样的操作,left在不断的向右移动,right在不断的向左移动但是它的下标也不会超出图1第二段区间的左边,这样我们就能够找到连续target的左边界。
图2
在这里插入图片描述
然后我们来处理两个细节问题,第一个问题就是这样使用二分查找,它的循环条件是使用left<right还是left<=right。我们朴素二分查找是使用后者的,但是在这里要使用前者。为什么呢,这里先分三种情况:
(1)target在right和left区间之内
在这种情况下,最终right会等于left,此时跳出循环即可,直接得到的下标就是正确答案,根本不需要去额外在循环当中去分三种情况> < ==。
(2)left和right区间内都是小于target的
此时left不断的加一最终和right相等跳出循环即可,然后判断nums[right]是否等于target。
(3)left和right区间内都是大于target
此时right不断向右最终和left相等跳出循环。
以上是选择left<right的原因之一,另一个原因就是使用left<=right会造成死循环,当我们使用图2中的方法来处理最终得到结果时,此时left等于right,如果使用left<=right下一次不会跳出而是会进入死循环,这一点还是很好理解的。
综上三种情况,我们使用left<right这样的循环条件,是因为当跳出循环时我们可以进行判断nums[right]是否等于target从而直接得到结果,另外可以防止死循环。
第二个细节问题就是中点的选择,一般是有两种方式来计算中点如图3。
图3
在这里插入图片描述
图3中两种计算中点的方式在朴素二分查找中都是可以适用的,但是这里也就是按照图2的计算方式来说两种方式是有差别的,如果我们使用第二种计算方式,如果我们将left和right的区间缩小到两个元素,也就是left+1等于right这种情况,此时mid计算为right,nums[mid]等于target,right=mid,后面的循环mid经过计算又等于原来的值,由此进入死循环,为了避免这种情况我们就需要使用第一种计算中点的方式。
以上就是求连续的target左边界的分析,对于右边界的分析也是类似的,唯一需要注意的就是此时计算中点的方式要选择第二种否则会造成死循环。
优化后代码如下:

class Solution {public int[] searchRange(int[] nums, int target) {int left1 = 0, right1 = nums.length - 1;if (right1 == -1) {return new int[] { -1, -1 };}int[] ret = new int[2];while (left1 < right1) {int mid1 = left1 + (right1 - left1) / 2;if (nums[mid1] < target) {left1 = mid1 + 1;} else {right1 = mid1;}}if (nums[right1] == target) {ret[0] = right1;} else {ret[0] = -1;}int left2 = 0, right2 = nums.length - 1;while (left2 < right2) {int mid2 = left2 + (right2 - left2 + 1) / 2;if (nums[mid2] > target) {right2 = mid2 - 1;} else {left2 = mid2;}}if (nums[left2] == target) {ret[1] = left2;} else {ret[1] = -1;}return ret;}
}

解题模板:
在这里插入图片描述
下面出现减一上面就需要加一。
题目链接

3. 搜索插入位置(35)

题目描述:
在这里插入图片描述
在这里插入图片描述

算法原理:
根据题目知道,这里的数组是一个升序并且无重复元素的数组,并且如果数组内包含target就求出target的下标,如果数组中不包含target就求出第一个大于target的数的下标,这就是题目的要求。那么我们就可以将数组分为两部分,第一部分是小于target的部分,第二个部分是大于等于target的部分,那么我们直接求出第二部分的左边界即可。前面的题目我们也给出了模板以及解题的思路,具体看代码。
代码如下:

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

题目链接

4. x 的平方根 (69)

题目描述:
在这里插入图片描述

算法原理:
根据题目我们知道可以将1到x就当成数组中的数,然后我们需要去找到一个数n去满足n*n等于x,这个n就可以使用二分查找来进行寻找,将1到x分为两部分,一部分是数的平方小于等于x另一部分是数的平方大于x,显然我们只需要找到第一部分的右边界即可。不过这题提交的时候要注意数据溢出的问题,要确定好数的类型。
代码如下:

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

题目链接

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

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

相关文章

七天速通javaSE:第五天 数组基础

文章目录 前言一、认识数组二、数组的声明和创建1. 声明数组变量2. 创建数组3. 变量的初始化&#xff08;赋值&#xff09;3.1 静态初始化3.2 动态初始化 3. 示例 三、数组的使用1. 循环1.1 普通for循环1.2 For-Each 循环 2. 数组作为函数的参数和返回值 前言 本文将为大家介绍…

Win11 Python3.10 安装pytorch3d

0&#xff0c;背景 Python3.10、cuda 11.7、pytorch 2.0.1 阅读【深度学习】【三维重建】windows10环境配置PyTorch3d详细教程-CSDN博客 1&#xff0c;解决方法 本来想尝试&#xff0c;结果发现CUB安装配置对照表里没有cuda 11.7对应的版本&#xff0c;不敢轻举妄动&#x…

DP:子序列问题

文章目录 什么是子序列子序列的特点举例说明常见问题 关于子序列问题的几个例题1.最长递增子序列2.摆动序列3.最长递增子序列的个数4.最长数对链5.最长定差子序列 总结 什么是子序列 在计算机科学和数学中&#xff0c;子序列&#xff08;Subsequence&#xff09;是指从一个序列…

c语言的烫烫烫烫烫??

当初学习C语言时&#xff0c;对于一些特殊的打印输出可能会感到困惑&#xff0c;比如会出现一堆乱码烫烫烫的情况。其实这是因为在C语言中&#xff0c;对于字符类型和数字类型之间的隐式转换可能会导致打印输出的结果不符合预期。这并不意味着程序员"烫"&#xff0c;…

[激光原理与应用-96]:激光器研发与生产所要的常见设备(大全)与仪器(图解)

目录 一、激光器制造设备 二、测试与校准设备 2.1 光功率计&#xff1a; 1、工作原理 2、主要功能 3、应用场景 4、测量方法 5、总结 2.2. 激光束质量分析仪&#xff1a; 1、概述 2、主要功能和特点 3、工作原理 4、常见品牌和型号 5、应用领域 6、总结 2.3 光…

基于大数据架构的情感分析

1 项目介绍 1.1 研究目的和意义 随着大数据时代的到来&#xff0c;电影产业积累了海量的用户评论数据&#xff0c;这些数据中蕴含着观众的情感倾向与偏好信息&#xff0c;为电影推荐和市场策略制定提供了宝贵资源。然而&#xff0c;如何高效地从这浩瀚的数据海洋中提炼出有价…

QT5:在窗口右上角显示图标

目录 一、环境与目标 二、实现逻辑&#xff08;纯代码&#xff09;与效果 三、参考代码 四、总结 一、环境与目标 qt版本&#xff1a;5.12.7 windows 11 下的 Qt Designer &#xff08;已搭建&#xff09; 目标&#xff1a;使用嵌套布局的方式将两个按钮显示在窗口右上角…

《大海》这歌为何经久不衰?你看歌词写的多美妙!

《大海》这歌为何经久不衰&#xff1f;你看歌词写的多美妙&#xff01; 《大海》是一首由陈大力作词&#xff0c;陈大力、陈秀男作曲&#xff0c;Ricky Ho编曲&#xff0c;张雨生演唱的国语流行歌曲。该曲收录在张雨生1992年11月30日由飞碟唱片发行的同名专辑《大海》中。 作为…

【JavaEE精炼宝库】多线程进阶(2)synchronized原理、JUC类——深度理解多线程编程

一、synchronized 原理 1.1 基本特点&#xff1a; 结合上面的锁策略&#xff0c;我们就可以总结出&#xff0c;synchronized 具有以下特性(只考虑 JDK 1.8)&#xff1a; 开始时是乐观锁&#xff0c;如果锁冲突频繁&#xff0c;就转换为悲观锁。 开始是轻量级锁实现&#xff…

广州外贸建站模板

Yamal外贸独立站wordpress主题 绿色的亚马尔Yamal外贸独立站wordpress模板&#xff0c;适用于外贸公司建独立站的wordpress主题。 https://www.jianzhanpress.com/?p7066 赛斯科Sesko-W外贸建站WP主题 适合机械设备生产厂家出海做外贸官网的wordpress主题&#xff0c;红橙色…

Dify自定义工具例子

1.天气&#xff08;JSON&#xff09; {"openapi": "3.1.0","info": {"title": "Get weather data","description": "Retrieves current weather data for a location.","version": "v1…

动态规划——打家劫舍(C++)

好像&#xff0c;自己读的书确实有点少了。 ——2024年7月2日 198. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; 题目描述 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连…

【Node-RED 4.0.2】4.0版本新增特性(官方版)

二、重要功能 *1.时间戳格式改进 过去&#xff0c;node-red 只提供了 最原始的 timestamp 的格式&#xff08;1970-01-01 ~ now&#xff09; 但是现在&#xff0c;额外增加了 2 种格式&#xff1a; ISO 8601 -A COMMON FORMAT&#xff08;YYYY-MM-DDTHH:mm:ss:sssZ&#xff…

思考如何学习一门编程语言?

一、什么是编程语言 编程语言是一种用于编写计算机程序的人工语言。通过编程语言&#xff0c;程序员可以向计算机发出指令&#xff0c;控制计算机执行各种任务和操作。编程语言由一组语法规则和语义规则组成&#xff0c;这些规则定义了如何编写代码以及代码的含义。 编程语言…

linux和mysql基础指令

Linux中nano和vim读可以打开记事文件。 ifdown ens33 ifup ens33 关闭&#xff0c;开启网络 rm -r lesson1 gcc -o code1 code1.c 编译c语言代码 ./code1 执行c语言代码 rm -r dir 删除文件夹 mysql> show databases-> ^C mysql> show databases; -------…

【C++进阶学习】第五弹——二叉搜索树——二叉树进阶及set和map的铺垫

二叉树1&#xff1a;深入理解数据结构第一弹——二叉树&#xff08;1&#xff09;——堆-CSDN博客 二叉树2&#xff1a;深入理解数据结构第三弹——二叉树&#xff08;3&#xff09;——二叉树的基本结构与操作-CSDN博客 二叉树3&#xff1a;深入理解数据结构第三弹——二叉树…

想要打造超高性能的接口API?试试这12条小技巧。

1. 并行处理 简要说明 举个例子&#xff1a;在价格查询链路中&#xff0c;我们需要获取多种独立的价格配置项信息&#xff0c;如基础价、折扣价、商户活动价、平台活动价等等。 CompletableFuture 是银弹吗&#xff1f; 使用 CompletableFuture 的确能够帮助我们解决许多独…

Android自动化测试实践:uiautomator2 核心功能与应用指南

Android自动化测试实践&#xff1a;uiautomator2 核心功能与应用指南 uiautomator2 是一个用于Android应用的自动化测试Python库&#xff0c;支持多设备并行测试操作。它提供了丰富的API来模拟用户对App的各种操作&#xff0c;如安装、卸载、启动、停止以及清除应用数据等。此外…

30个!2024重大科学问题、工程技术难题和产业技术问题发布

【SciencePub学术】中国科协自2018年开始&#xff0c;组织开展重大科技问题难题征集发布活动&#xff0c;引导广大科技工作者紧跟世界科技发展大势&#xff0c;聚焦国家重大需求&#xff0c;开展原创性、引领性研究&#xff0c;不断夯实高质量发展的科技支撑。 自2024年征集活动…

C#的五大设计原则-solid原则

什么是C#的五大设计原则&#xff0c;我们用人话来解释一下&#xff0c;希望小伙伴们能学会&#xff1a; 好的&#xff0c;让我们以一种幽默的方式来解释C#的五大设计原则&#xff08;SOLID&#xff09;&#xff1a; 单一职责原则&#xff08;Single Responsibility Principle…