力扣经典面试题——搜索旋转排序数组及最小值(二分搜索旋转数组系列一次搞定)

我们先来看看一个常规的二分搜索是如何进行的?
例如要找一个有序数组的某个数
【1,2,4,5,9,11,15,19】
我们要找11,每次我们分割半边判断然后看到底在哪一边。
这里为什么我们可以直接砍掉半边?因为数组有序,如果要找的数比mid大,那么一定不在左半边。
带着上面的这种思想,进入正题:
先来看这个搜索旋转排序数组:https://leetcode.cn/problems/search-in-rotated-sorted-array/description/?envType=study-plan-v2&envId=top-100-liked
我们发现,这个数组分割为了两个有序的数组。这个就会让我们想到两次二分。即找到那个第一次下降的点,然后左边二分右边二分。但是如果要找到这个点我们一定要遍历整个数组,时间复杂度O(n),虽然能过这题,但是这个和题目要求的Logn复杂度差得远。
既然复杂度只能是logn说明了什么?说明我们一定可以直接通过二分得到答案
在这里插入图片描述好,我们来看如何一步步推出结论。首先我们先尝试着二分看看,如果我们二分,就会出现这种情况,就是二分得到的点,左边右边并不是严格递增,如果一个数小于mid那么可能会导致他不在mid前面而是在mid后面。这样我们砍不掉半边。但是我们这个时候观察到,左右半边一定会有一个半边递增,那么我们可以局部判断,就看哪里递增,我们只需要判断目标在不在那个有序的半边,不在就二分另外半边,怎么判断哪个半边有序,直接首尾看看递不递增就行了。
故得到思路:由于这个是一个旋转数组,所以如果找到一个分割点一定可以保证一个半边是有序的,然后根据这个有序的半边可以判断target在不在这个半边,如果在那么就递归这个半边,不然就另外半个。

class Solution {public int search(int[] nums, int target) {//思路:由于这个是一个旋转数组,所以如果找到一个分割点//一定可以保证一个半边是有序的,然后根据这个有序的半边可以判断//target在不在这个半边,如果在那么就递归这个半边,不然就另外半个int left = 0;int right = nums.length-1;while(left<=right){int mid = (left+right)/2;if(target==nums[mid])return mid;//后面半边是否有序,即找到有序的半边进if(nums[mid]<=nums[right]){//看target在不在这个半边if(nums[mid]<=target&&target<=nums[right]){left = mid+1;}else{right = mid-1;}}else{if(nums[left]<=target&&target<=nums[mid]){right = mid-1;}else{left = mid+1;}}}return -1;}
}

再来看另外一个,寻找旋转排序数组中的最小值。https://leetcode.cn/problems/find-minimum-in-rotated-sorted-array/?envType=study-plan-v2&envId=top-100-liked
这次我们要找的其实就是那个旋转的起始点,也就是整个数组的最小值。思路类似,由于旋转的点一定在不递增的半边,所以根据这个特征二分就行了,还有一个点就是如果都递增怎么办?思考过后再看后面的答案
在这里插入图片描述核心思路:找非递增的半边,如果都递增那么就找小的半边。

class Solution {public int findMin(int[] nums) {//找非递增的半边,如果都递增那么就找小的半边int left = 0;int right = nums.length-1;while(left<right){int mid = (left+right)/2;//有不递增的一边if(nums[mid]<nums[left]||nums[mid]>nums[right]){if(nums[mid]<nums[left]){right = mid;}else{left = mid+1;}}//两边都递增else{right = mid;}}return nums[left];}
}

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

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

相关文章

TCP 三次握手:四次挥手

TCP 三次握手/四次挥手 TCP 在传输之前会进行三次沟通&#xff0c;一般称为“三次握手”&#xff0c;传完数据断开的时候要进行四次沟通&#xff0c;一般称为“四次挥手”。 数据包说明 源端口号&#xff08; 16 位&#xff09;&#xff1a;它&#xff08;连同源主机 IP 地址…

sql_lab之sqli注入中的cookie注入

Cookei注入&#xff08;gxa的从cookei注入&#xff09; 1.打开控制台 2.验证id2时的值 document.cookie"id2" 3.判断是上面闭合方式 document.cookie"id2 -- s" 有回显 说明是’单引号闭合 4.用order by 判断字段数 5.用联合查询判断回显点 接下来的…

Flowable-升级为7.0.0.M2-第一节

目录 升级jdk升级springboot到3.1.3升级数据库连接池druid-spring-boot-3-starter到1.2.20升级mybatis-plus到3.5.3.2升级flowable到7.0.0.M2 最近有些读者一直问flowable如何升级到7.0.0.M2&#xff0c;接下来我就一步步的把flowable升级到7.0.0.M2 升级jdk flowable7.x采用的…

框架面试题

文章目录 1. spring中的bean是线程安全的吗2. 事务的实现--AOP3. 项目中用到的AOP4.spring中事务的失效场景5. Bean的生命周期6.spring中的循环引用问题7. springMVC的执行流程8. springboot自动装配原理9. 常见注解10 Mybatis11 Mybatis一二级缓存 1. spring中的bean是线程安全…

docker的一些思考

1.docker是啥&#xff1f; 2.镜像执行流程 3.一些疑惑和解答 1. 2.

【教学类-42-03】20231225 X-Y 之间加法题判断题3.0(确保错误题有绝对错误的答案)

背景需求&#xff1a; 根据需求&#xff0c;0-5以内的判断是21题正确&#xff0c;21题错误&#xff0c;但由于错误答案是随机数抽取&#xff0c;有可能恰好是正确的&#xff0c;所以会出现每套题目的正确数和错误数不一样的情况 优化思路一&#xff1a; 设置如果错误答案与正…

图像九宫格切分1x3、3x3 Python

文章目录 1、需求2、实现2-1 贴图、切分2-2 GUI 3、运行效果4、代码 1、需求 把一个图像切分成 1x3 或者 3x3切分出来的图像比例希望都是 1:1 正方形如果图像尺寸满足 切分条件&#xff0c;自动填充一些“白边”然后继续切分如果填充了白边的话&#xff0c;希望能够调整原图像…

Go 语言实战:掌握正则表达式的应用与技巧

Go 语言实战&#xff1a;掌握正则表达式的应用与技巧 1. 引言2. 正则表达式基础2.1 基本概念2.2 常见元素2.3 基本示例 3. Go语言中的正则表达式库3.1 引入regexp包3.2 编译正则表达式3.3 使用正则表达式3.4 示例代码 4. 常用正则表达式函数及使用示例4.1 MatchString4.2 FindS…

数据库01_增删改查

1、什么是数据&#xff1f;什么是数据库&#xff1f; 数据&#xff1a;描述事物的符号记录称为数据。数据是数据库中存储的基本对象。数据库&#xff1a;存放数据的仓库&#xff0c;数据库中可以保存文本型数据、二进制数据、多媒体数据等数据 2、数据库的发展 第一阶段&…

Fireblock:为Dapp实现可编程隐私

1. 引言 Fireblock network为Cosmos生态应用链。并于2023年10月宣布完成pre-seed轮250万美金融资。 其定位为实现&#xff1a; 有条件解密可编程隐私 Fireblock使用的密码学方案有&#xff1a; distributed key generation&#xff08;DKG&#xff09;Identity-based encry…

数据库开发之多表查询的详细解析

1. 多表查询 1.1 概述 1.1.1 数据准备 SQL脚本&#xff1a; #建议&#xff1a;创建新的数据库 create database db04; use db04; ​ -- 部门表 create table tb_dept (id int unsigned primary key auto_increment comment 主键ID,name varchar(10) not nu…

前端测试——端对端测试框架 Playwright 总结

在进行前端测试前&#xff0c;我们需要明确我们需要怎样的前端测试。 前端测试类型总结 前端应用测试分为几种常见类型: 端到端&#xff08;e2e&#xff09; &#xff1a;一个辅助机器人&#xff0c;表现得像一个用户&#xff0c;在应用程序周围点击&#xff0c;并验证其功能…