当前位置: 首页 > news >正文

【LeetCode】33.搜索旋转排序数组

欢迎来到李耶的频道【LeetCode面试题】。


搜索旋转排序数组

33.搜索旋转排序数组

题目

整数数组nums按升序排列,数组中的值互不相同

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

给你旋转后的数组nums和一个整数target,如果nums中存在这个目标值target,则返回它的下标,否则返回-1

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

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

提示:

  • 1 <= nums.length <= 5000
  • -10^4 <= nums[i] <= 10^4
  • nums中的每个值都独一无二
  • nums肯定会在某个点上旋转
  • -10^4 <= target <= 10^4

解法一:二分查找(一次遍历)

思路:旋转排序数组从中间切开时,至少有一半是连续递增的。利用这一点,在二分查找中判断target是否落在有序的那一半,从而缩小搜索范围。关键步骤是判断[left, mid]区间是否有序。

functionsearch(nums,target){letleft=0;letright=nums.length-1;while(left<=right){constmid=Math.floor((left+right)/2);if(nums[mid]===target)returnmid;// 判断左半部分 [left, mid] 是否有序if(nums[left]<=nums[mid]){// 左半部分有序,判断 target 是否在左半部分范围内if(nums[left]<=target&&target<nums[mid]){right=mid-1;// 在左半部分查找}else{left=mid+1;// 在右半部分查找}}else{// 右半部分 [mid, right] 有序if(nums[mid]<target&&target<=nums[right]){left=mid+1;// 在右半部分查找}else{right=mid-1;// 在左半部分查找}}}return-1;}
  • 时间复杂度 / 空间复杂度:O(log n) / O(1)
  • 优势:一次遍历完成查找,空间 O(1),是面试中最推荐的写法

解法二:先找旋转点,再二分查找

思路:先通过二分查找找到数组的最小元素(旋转点),将数组划分为两个有序部分。然后根据target的值决定在哪个有序部分进行标准二分查找。

functionsearch(nums,target){constn=nums.length;if(n===0)return-1;// 1. 二分查找找旋转点(最小值下标)letleft=0;letright=n-1;while(left<right){constmid=Math.floor((left+right)/2);if(nums[mid]>nums[right]){left=mid+1;}else{right=mid;}}constpivot=left;// 2. 确定 target 在哪个有序区间letl,r;if(target>=nums[pivot]&&target<=nums[n-1]){l=pivot;r=n-1;}else{l=0;r=pivot-1;}// 3. 标准二分查找while(l<=r){constmid=Math.floor((l+r)/2);if(nums[mid]===target)returnmid;if(nums[mid]<target){l=mid+1;}else{r=mid-1;}}return-1;}
  • 时间复杂度 / 空间复杂度:O(log n) / O(1)
  • 优势:逻辑分步清晰,将复杂问题拆解为"找旋转点 + 标准二分查找"

解法对比

解法时间 / 空间复杂度优势推荐指数
二分查找(一次遍历)O(log n) / O(1)代码简洁,一次遍历完成⭐⭐⭐⭐⭐
先找旋转点再二分O(log n) / O(1)分步逻辑清晰,易于理解⭐⭐⭐⭐

扩展题

  1. 搜索旋转排序数组 II:与本题相同,但数组可能包含重复元素,搜索指定目标值。
  2. 寻找旋转排序数组中的最小值:寻找旋转排序数组中的最小元素。
  3. 搜索二维矩阵:编写一个高效的算法来判断m x n矩阵中是否存在一个目标值,矩阵具有特性:每行每列均按升序排列。

“举一隅不以三隅反,则不复也。” —— 《论语·述而》

关注李耶,每天一道面试题,一起卷起来 🔥

http://www.jsqmd.com/news/1364976/

相关文章:

  • 猎户Orion9系列:高精度惯性导航技术解析与应用
  • 白龙桥聚餐全攻略 | 塔石土菜馆实测:家庭团建夜宵一店搞定
  • DDD架构实战:领域驱动设计的核心价值与应用
  • 2026年靠谱打酒铺推荐3家热门榜,快来一探究竟! - 企业推荐官
  • 智能农业物联网系统:传感器+云平台+小程序完整方案
  • C语言-作业
  • MongoDB实战指南:从安装部署到性能优化
  • AI与人类学习机制对比及高效视频学习法
  • C# 2019开发ERP系统:核心技术解析与实践
  • 化工项目投标需要金属管浮子流量计,哪些厂家有石化行业供货业绩 - 仪表人小余
  • V2G技术中用户响应建模与调度优化实践
  • 第11篇_Server 07|用通信猫、curl 和在线变量完成真机验收
  • VisionMaster 断续划痕检测全流程算子实操详解
  • BetterGI原神AI工具:从繁琐操作到智能游戏的终极解决方案
  • 微流控血脑屏障芯片技术解析与应用
  • Spring IOC容器启动流程与Bean生命周期详解
  • 一级减速器CAD图纸设计规范与核心要点解析
  • Android框架开发核心技术与实践指南
  • Python音频处理实战:基于pydub实现音频剪辑、混合与自动化
  • HCIA学习笔记(六):IP编址基础概念
  • 从零配置OGRE 3D引擎:C++图形开发入门与旋转立方体实战
  • 0391-Raylib-按钮动画和声音
  • 3分钟快速修复洛雪音乐:六音音源修复版完全指南
  • OpenClaw容器化部署实战:Docker与CUDA环境配置指南
  • 在VS2010中从零实现FFT算法:原理、代码与性能优化实战
  • XUnity.AutoTranslator:Unity游戏一键翻译的终极解决方案
  • 信息系统项目管理师备考全攻略:从教材精读到论文实战
  • Python实战:基于规则与NER的军事战报信息抽取与结构化处理
  • AI文章转PPT视频:本地部署与自动化流程全解析
  • Python高级特性实战:提升代码效率与性能