二分查找题目:搜索旋转排序数组

【忍者算法】探秘旋转数组:二分查找的华丽转身!|LeetCode 33「搜索旋转排序数组」 大家好,我是忍者算法。今天要和大家分享一道特别有趣的题目 - LeetCode 33「搜索旋转排序数组」。这道题巧妙地将二分查找与旋转数组结合,是一道考察思维灵活性的经典题目。想象你在看一个圆形时钟,如果把时钟的12点位置当作起点,顺时针记录1到12这些数字,这就是一个有序序列。现在,如果我们把时钟的指针从8点开始读数,到12点,再到7点,实际上就形成了一个"旋转"后的有序序列:8,9,10,11,12,1,2,3,4,5,6,7。这正是我们今天要处理的"旋转排序数组"!题目要求: 给你一个整数数组 num 阅读详情

题目

标题和出处

标题:搜索旋转排序数组

出处:33. 搜索旋转排序数组

难度

5 级

题目描述

要求

整数数组 nums \texttt{nums} nums 按升序排序,数组中的值各不相同。

在传递给函数之前, nums \texttt{nums} nums 可能在预先未知的某个下标 k \texttt{k} k( 0 ≤ k < nums.length \texttt{0} \le \texttt{k} < \texttt{nums.length} 0≤k<nums.length)上进行了旋转,使数组变为 [nums[k],   nums[k+1],   ...,   nums[n-1],   nums[0],   nums[1],   ...,   nums[k-1]] \texttt{[nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]} [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标从 0 \texttt{0} 0 开始计数)。例如, [0,1,2,4,5,6,7] \texttt{[0,1,2,4,5,6,7]} [0,1,2,4,5,6,7] 可能在下标 3 \texttt{3} 3 处旋转,变为 [4,5,6,7,0,1,2] \texttt{[4,5,6,7,0,1,2]} [4,5,6,7,0,1,2]。

给定可能经过旋转后的数组 nums \texttt{nums} nums 和一个整数 target \texttt{target} target,如果 nums \texttt{nums} nums 中存在目标值 target \texttt{target} target,则返回它的下标,否则返回 -1 \texttt{-1} -1。

要求时间复杂度是 O(log   n) \texttt{O(log n)} O(log n)。

示例

示例 1:

输入: nums   =   [4,5,6,7,0,1,2],   target   =   0 \texttt{nums = [4,5,6,7,0,1,2], target = 0} nums = [4,5,6,7,0,1,2], target = 0
输出: 4 \texttt{4} 4

示例 2:

输入: nums   =   [4,5,6,7,0,1,2],   target   =   3 \texttt{nums = [4,5,6,7,0,1,2], target = 3} nums = [4,5,6,7,0,1,2], target = 3
输出: -1 \texttt{-1} -1

示例 3:

输入: nums   =   [1],   target   =   0 \texttt{nums = [1], target = 0} nums = [1], target = 0
输出: -1 \texttt{-1} -1

数据范围

  • 1 ≤ nums.length ≤ 5000 \texttt{1} \le \texttt{nums.length} \le \texttt{5000} 1≤nums.length≤5000
  • -10 4 ≤ nums[i] ≤ 10 4 \texttt{-10}^\texttt{4} \le \texttt{nums[i]} \le \texttt{10}^\texttt{4} -104≤nums[i]≤104
  • nums \texttt{nums} nums 中的每个值各不相同
  • nums \texttt{nums} nums 是升序数组,可能进行了旋转
  • -10 4 ≤ target ≤ 10 4 \texttt{-10}^\texttt{4} \le \texttt{target} \le \texttt{10}^\texttt{4} -104≤target≤104

解法

思路和算法

这道题中给定的数组是将升序数组可能旋转之后的数组。将升序数组旋转之后得到的数组整体不是有序的,但是可以分成两个有序子数组,因此同样可以使用二分查找的方法查找目标值。

由于数组中的每个值各不相同,因此如果数组经过旋转,则旋转之后的数组的首元素一定大于末尾元素。对于数组中的任意数,可以根据该数与数组的首元素和末尾元素的大小关系得到其在哪个有序子数组中。

用 low \textit{low} low 和 high \textit{high} high 分别表示二分查找的下标范围的下界和上界,初始时 low \textit{low} low 和 high \textit{high} high 分别为数组的最小下标和最大下标。每次查找时, [ low , high ] [\textit{low}, \textit{high}] [low,high] 可能是一个有序子数组或者两个有序子数组,取 mid \textit{mid} mid 为 low \textit{low} low 和 high \textit{high} high 的平均数向下取整,得到下标 mid \textit{mid} mid 处的数,判断该数是否等于目标值以及位于哪一个有序子数组中,调整查找的下标范围。

  • 如果 nums [ mid ] = target \textit{nums}[\textit{mid}] = \textit{target} nums[mid]=target,则找到目标值,返回其下标 mid \textit{mid} mid。

  • 如果 nums [ low ] ≤ nums [ mid ] \textit{nums}[\textit{low}] \le \textit{nums}[\textit{mid}] nums[low]≤nums[mid],则下标范围 [ low , high ] [\textit{low}, \textit{high}] [low,high] 中有一个有序子数组或者两个有序子数组,下标 mid \textit{mid} mid 位于以下标 low \textit{low} low 开始的有序子数组中。此时将目标值与 nums [ low ] \textit{nums}[\textit{low}] nums[low] 和 nums [ mid ] \textit{nums}[\textit{mid}] nums[mid] 比较,调整查找的下标范围。

    • 如果 nums [ low ] ≤ target < nums [ mid ] \textit{nums}[\textit{low}] \le \textit{target} < \textit{nums}[\textit{mid}] nums[low]≤target<nums[mid],则如果目标值存在,一定位于下标范围 [ low , mid − 1 ] [\textit{low}, \textit{mid} - 1] [low,mid−1] 中,因此在下标范围 [ low , mid − 1 ] [\textit{low}, \textit{mid} - 1] [low,mid−1] 中继续查找。

    • 否则,如果目标值存在,一定位于下标范围 [ mid + 1 , high ] [\textit{mid} + 1, \textit{high}] [mid+1,high] 中,因此在下标范围 [ mid + 1 , high ] [\textit{mid} + 1, \textit{high}] [mid+1,high] 中继续查找。

  • 如果 nums [ low ] > nums [ mid ] \textit{nums}[\textit{low}] > \textit{nums}[\textit{mid}] nums[low]>nums[mid],则下标范围 [ low , high ] [\textit{low}, \textit{high}] [low,high] 中有两个有序子数组,下标 mid \textit{mid} mid 位于以下标 high \textit{high} high 结束的有序子数组中。此时将目标值与 nums [ high ] \textit{nums}[\textit{high}] nums[high] 和 nums [ mid ] \textit{nums}[\textit{mid}] nums[mid] 比较,调整查找的下标范围。

    • 如果 nums [ mid ] < target ≤ nums [ high ] \textit{nums}[\textit{mid}] < \textit{target} \le \textit{nums}[\textit{high}] nums[mid]<target≤nums[high],则如果目标值存在,一定位于下标范围 [ mid + 1 , high ] [\textit{mid} + 1, \textit{high}] [mid+1,high] 中,因此在下标范围 [ mid + 1 , high ] [\textit{mid} + 1, \textit{high}] [mid+1,high] 中继续查找。

    • 否则,如果目标值存在,一定位于下标范围 [ low , mid − 1 ] [\textit{low}, \textit{mid} - 1] [low,mid−1] 中,因此在下标范围 [ low , mid − 1 ] [\textit{low}, \textit{mid} - 1] [low,mid−1] 中继续查找。

如果查找的过程中出现 low > high \textit{low} > \textit{high} low>high,则目标值不存在,返回 − 1 -1 −1。

代码

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

复杂度分析

  • 时间复杂度: O ( log ⁡ n ) O(\log n) O(logn),其中 n n n 是数组 nums \textit{nums} nums 的长度。二分查找的次数是 O ( log ⁡ n ) O(\log n) O(logn),每次查找的时间是 O ( 1 ) O(1) O(1),时间复杂度是 O ( log ⁡ n ) O(\log n) O(logn)。

  • 空间复杂度: O ( 1 ) O(1) O(1)。

保姆级教程:在Ubuntu 22.04上搞定PX4 V1.14 + ROS2 Humble的HITL仿真(避坑实录) 本文提供在Ubuntu 22.04上配置PX4 V1.14与ROS2 Humble的HITL仿真环境的详细教程,涵盖环境准备、固件编译、QGroundControl配置、ROS2通信设置及联调测试。特别针对版本兼容性、Gazebo插件构建和MicroDDS配置等常见问题提供避坑指南,帮助开发者高效搭建无人机仿真系统。 阅读详情

相关推荐

S32DS IDE调试技巧:如何用Attach功能高效定位汽车电子MCU的Bootloader问题

本文详细介绍了在汽车电子MCU开发中,如何利用S32DS IDE的Attach调试模式高效定位Bootloader与应用程序的协同问题。通过对比常规调试与Attach模式的本质差异,并深入讲解工程配置、镜像合并及实战调试流程,帮助开发者在不复位、不重新下载程序的前提下,实时分析系统状态,快速解决内存映射冲突、中断向量表重定向等疑难杂症。

weixin_29168393的博客 270

二分查找题目:搜索旋转排序数组 II

这道题也可以使用二分查找的思想,但是由于数组中可能存在重复元素,因此无法保证达到二分查找的时间复杂度。三个元素不完全相等,则可以根据这三个元素值与目标值的大小关系确定目标值可能出现的下标范围,调整查找的下标范围。处的数,判断该数是否等于目标值以及位于哪一个有序子数组中,调整查找的下标范围。,则无法确定两个非递减子数组的分界位置(即第二个非递减子数组的开始下标)是在。时,整个数组是一个非递减数组,即第二个非递减子数组的长度是。的右边,此时无法将查找的下标范围缩小一半,因此在下标范围。开始的有序子数组中。

stormsunshine的博客 637

Apollo control模块横向控制原理及核心代码逐行解析

看完这篇文章,你会对apollo横向控制有一个整体的概念

weixin_39199083的博客 2万+

【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值

【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值

阿旭的博客 1435

Abaqus 单元与全局刚度矩阵导出实战指南:从INP修改到结果解析

本文提供了Abaqus中导出单元刚度矩阵和全局刚度矩阵的完整实战指南。通过详细步骤讲解INP文件修改、关键指令插入及结果文件解析,帮助工程师、研究人员和二次开发者深入理解有限元软件内核,实现理论验证、二次开发与深度问题调试。

k8s6orchestrator的博客 900

避开命令行!在VMware vCenter 8.0图形化界面里搞定SSL证书续期全流程

本文详细介绍了在VMware vCenter 8.0图形化界面中完成SSL证书续期的全流程,包括计算机SSL证书、VMCA根证书和STS证书的管理。通过可视化操作,管理员无需使用命令行即可高效处理证书问题,确保vSphere环境的稳定运行。文章还提供了证书监控与预警配置的实用技巧,帮助用户提前规避证书过期风险。

weixin_27051161的博客 284

[LeetCode]81. 搜索旋转排序数组 II(java实现)二分

[LeetCode]81. 搜索旋转排序数组 II(java实现)二分1. 题目2. 读题(需要重点注意的东西)3. 解法4. 可能有帮助的前置习题5. 所用到的数据结构与算法思想6. 总结 1. 题目 2. 读题(需要重点注意的东西) 思路: 直接遍历一遍,最坏情况下时间复杂度为O(n) 删除给定的旋转数组结尾的和nums[0]相同的数,然后按[LeetCode] 33. 搜索旋转排序数组(java实现)二分进行二分,当所有数都相同时,二分会退化成线性搜索,即最坏情况下时间复杂度为O(n) 3.

cloud的博客 513

dify离线部署

以bge-m3为例,本地部署bge-m3首先在一台能连网的linux服务器上(部署有ollama)创建想要保存模型的文件夹编辑ollama.service,配置ollama模型的保存路径添加模型存储地址将models目录设置属主,必须做,否则ollama无法启动重新加载配置文件并重启ollama测试ollama 运行是否正常最后拉取 bge-m3可在/opt/LLMModels/bge_m3/models目录下看到拉取得模型使用tar命令压缩文件夹。

weixin_42538734的博客 3072

Java的HashMap实例使用,力扣(LeetCode)刷题第33题:搜索旋转排序数组

文章目录前言一、题目介绍二、解题思路1.分析题目2.代码部分三、总结 前言 [题目地址:搜索旋转排序数组] 一、题目介绍 给你一个整数数组 nums ,和一个整数 target 。 该整数数组原本是按升序排列,但输入时在预先未知的某个点上进行了旋转。(例如数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 请你在数组中搜索 target ,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。 示例 1: 输入:nums = [4,5,6,7,0,1,2], tar

代码届的小白的博客 401

【制作100个unity实战之2】实现一款简单的FPS游戏

你将学到: fps武器脚本 基础瞄准功能 僵尸敌人AI 巡逻范围 攻击间 搜寻半径 追击 枪声吸引周围的僵尸 击中僵直效果

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 3552

PyTorch实战(7)——循环神经网络

本节介绍了循环神经网络 (RNN) 及其在序列数据处理中的应用。首先对比了卷积神经网络 (CNN) 与 RNN 的差异,指出 RNN 通过循环连接建模时序依赖关系。随后详细梳理了 RNN 的发展历程,包括基础 RNN、双向 RNN、LSTM、GRU 等变体的结构特点及改进动机,其中 LSTM 通过门控机制解决长程依赖问题,GRU 则进一步简化结构。接着通过 IMDb 情感分析实战,演示了如何使用 PyTorch 实现文本预处理、RNN 模型构建及训练评估流程,最后探讨了注意力机制如何提升 RNN 性能。

盼小辉丶的博客 1万+

旋转排列数组题-二分

参考【leetcode题解】 文章目录33. 搜索旋转排序数组(不重复,查找特别值)81. 搜索旋转排序数组 II(重复,查找特定值)153. 寻找旋转排序数组中的最小值(不重复,寻找最小值)154. 寻找旋转排序数组中的最小值 II(重复,寻找最小值) 33. 搜索旋转排序数组(不重复,查找特别值) 给你一个升序排列的整数数组 nums ,和一个整数 target 。 假设按照升序排序的数组在预先未知的某个点上进行了旋转。(例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2

zhaoxiaoba的博客 197

Windows10下安装VMware16虚拟机

由于本人系统为Windows 10 家庭中文版,无法安装Linux子系统WSL,虽然网上也有强制安装的方法,但为保险起见,还是把之前的VMware虚拟机重新进行安装,并浅浅记录一下安装过程。

沉香best的博客 865

leetcode 33、34、35 各种条件下的二分查找小结 Python

二分查找使用有两个条件 表必须有序(增或减,可包含重复值) 表必须为顺序存储结构 用起来的时候情况很多,但是都可以根据一个基本架构来稍微改变条件 def bs0(nums,target): l,r=0,len(nums)-1 while(l&amp;amp;amp;lt;=r): m=l+((r-l)/2)&amp;amp;amp;gt;&amp;amp;amp;gt;2 #话说之前这里掉了个括号。。。 if(...

Bismarckczy的博客 339

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

【LeetCode】33. 搜索旋转排序数组(假设按照升序排序的数组在预先未知的某个点上进行了旋转。)、34. 在排序数组中查找元素的第一个和最后一个位置

33. 搜索旋转排序数组 假设按照升序排序的数组在预先未知的某个点上进行了旋转。 ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。 你可以假设数组中不存在重复的元素。 你的算法时间复杂度必须是 O(log n) 级别。 示例 1: 输入: nums = [4,5,6...

qq_43109561的博客 2858

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

HOT100--Day22--74. 搜索二维矩阵,34. 在排序数组中查找元素的第一个和最后一个位置,33. 搜索旋转排序数组

HOT100–Day22–74. 搜索二维矩阵,34. 在排序数组中查找元素的第一个和最后一个位置,33. 搜索旋转排序数组 每日刷题系列。今天的题目是《力扣HOT100》题单。 题目类型:二分查找。 关键: 今天的题目都是“多次二分” 74题,掌握如何把有序矩阵,flatten成一维。 34题,懂得如何找元素的最左索引。 35题,懂得“翻转有序数组”的特性。如何找最小值的位置?要搜索怎么搜?

m0_60740070的博客 383

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

微软面试题:搜索旋转排序数组

假设有一个排序的按未知的旋转轴旋转的数组(比如,0 1 2 4 5 6 7 可能成为4 5 6 7 0 1 2)。给定一个目标值进行搜索,如果在数组中找到目标值返回数组中的索引位置,否则返回-1。你可以假设数组中不存在重复的元素。 看题解之前,可以试试→在线做题 例1: 输入: [4, 5, 1, 2, 3] and target=1, 输出: 2. 例2: 输入: [4, 5, 1, 2, 3] and target=0, 输出: -1. 【题解】 算法:二分 根据题目我们可以知道旋转数组实际上

LintCode的博客 176

leecode算法基础 第一天 二分查找

leetcode练习33搜索旋转排序数组34.在排序数组中查找元素的起始和结束位置 33搜索旋转排序数组   如果中间的数小于最右边的数,则右半段是有序的,若中间数大于最右边数,则左半段是有序的,我们只要在有序的半段里用首尾两个数组来判断目标值是否在这一区域内,这样就可以确定保留哪半边了。 public int search(int[] nums, int target) { int len = nums.length; int left = 0, right = len-1; wh

qq_43788026的博客 172

力扣LeetCode: 81 搜索旋转排序数组Ⅱ

已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同。

weixin_73982851的博客 554

二分查找的实现、特性及 力扣实战题目解析

二分查找的前提: 1.目标函数单调性(单调递增或递减) 2.存在上下界(bounded) 3.能够通过索引访问(index accessible) 代码模版 left , right = 0,len(array) - 1 while left <= right: mid = (left+right) / 2 if array[mid] == target: # find the target...

青柠小甜味 886

leetcode33.搜索螺旋排序数组——学习笔记

题目:力扣https://leetcode-cn.com/problems/search-in-rotated-sorted-array/ class Solution { public int search(int[] nums, int target) { int left = 0; int right = nums.length-1; while(left<=right){ int mid = (left+rig

Hokachi的博客 515

LeetCode 热题 100 精讲 | 二分查找篇:搜索插入位置 · 搜索旋转排序数组 · 在排序数组中查找首尾位置 · x 的平方根

LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置标准二分(搜索插入位置)、旋转数组中的二分(搜索旋转排序数组)、边界查找(查找首尾位置)、整数平方根(二分逼近)。掌握二分查找的核心在于理解循环不变式和边界条件的处理,特别是当时需要根据题目要求决定是返回还是继续收缩边界。建议刷题顺序:先做搜索插入位置巩固标准二分模板,再做平方根理解二分逼近思想,然后用旋转排序数组挑战复杂条件判断,最后用查找首尾位置掌握边界二分。下一篇将进入贪心算法篇(跳跃游戏、加油站等),敬请期待。免责声明。

2302_81155164的博客 734

LeetCode hot100-在排序数组中查找元素的第一个和最后一个位置和搜索旋转排序数组

本文介绍了两个基于二分查找的算法题解。第一题通过二分查找确定目标值的起始和结束位置,先找到第一个大于等于目标值的下标,再找到第一个大于目标值的下标减一,时间复杂度O(logn)。第二题在旋转排序数组中搜索目标值,通过判断中间点落在哪个有序区间来调整搜索范围,同样具有O(logn)的时间复杂度。两题都采用了双闭区间的二分查找实现,并注意处理边界条件。代码实现展示了如何通过二分查找高效解决有序数组和旋转数组的搜索问题。

2503_90669258的博客 250

【二分查找】寻找旋转排序数组中的最小值和点名

【0,1,2,3,4】 最开始少5 返回left+1。

2301_78983957的博客 29

LeetCode题解:搜索旋转排序数组

搜索旋转排序数组(middle) 更好的阅读体验应该是: 审题-思考 答题 整理-归纳 一、题目 LeetCode:33.搜索旋转排序数组 给你一个整数数组 nums ,和一个整数 target 。 该整数数组原本是按升序排列,但输入时在预先未知的某个点上进行了旋转。(例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 请你在数组中搜索 target ,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。 示例 1: 输入:nums = [4,5,6,

余光的博客 4000

二分查找进阶:旋转排序数组中的搜索II

本文介绍了在包含重复元素的旋转排序数组中搜索目标值的二分查找进阶方法。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 8383
上一篇: 二分查找题目:有序数组中的单一元素
下一篇: 二分查找题目:寻找旋转排序数组中的最小值
伟大的车尔尼
博客等级 码龄14年 2385粉丝 696原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大的车尔尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值