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

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) 的算法解决此问题。

示例 1:

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

示例 2:

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

示例 3:

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

提示:

  • 1 <= nums.length <= 5000
  • -104 <= nums[i] <= 104
  • nums 中的每个值都 独一无二
  • 题目数据保证 nums 在预先未知的某个下标上进行了旋转
  • -104 <= target <= 104

解法

注意旋转后数组的特点:

  • 4,5,6,7(最大),0(最小),1,2
  • 数组最左边的元素和最右边的元素在原来单调递增的数组中是相邻的
  • 数组从左到右,先是递增,然后到原来有序数组的第一个元素即最小值后,又开始递增
  • 从原来最小元素为分割点,左边的元素一定大于右边所有元素(包含最小元素)

根据以上特点,使用二分查找:

  • 旋转后的数组变成两个局部有序的数组 [4,5,6,7] 和 [0,1,2]
  • 每次找到mid后,先看 mid 为分割位置分割出来的两个部分 [l, mid] 和 [mid + 1, r] 哪个部分是有序的
  • 并根据有序的那个部分确定我们该如何改变二分查找的上下界
    1. 如果中间元素 >= 第一个元素:则说明中间元素在左边第一个元素到最大元素之间
    2. 反之(中间元素 <= 最后一个元素):则说明中间元素在原来最小元素和现在最右边元素之间

java代码:

class Solution {public int search(int[] nums, int target) {int n = nums.length;// 如果数组长度为0,返回-1if (n == 0) {return -1;}// 如果数组长度为1,直接比较元素与targetif (n == 1) {return nums[0] == target ? 0 : -1;}// 左索引从0开始int left = 0;// 右索引从末尾n-1开始int right = n - 1;// 使用二分查找while (left <= right) {// 求中间索引值midint mid = (left + right) / 2;// 如果mid索引对应值等于target,返回midif (nums[mid] == target) {return mid;}// 如果中间索引值大于等于第一个元素,则中间元素在左边第一个元素到最大元素之间if (nums[0] <= nums[mid]) {// 如果目标值>=第一个元素 && 目标值<中间元素// 说明目标值在左元素和中间元素之间(这部分是有序的),右索引=mid-1if (nums[0] <= target && target < nums[mid]) {right = mid -1;} else {// 否则说明目标值在中间元素和最后一个元素之间,左索引=mid+1left = mid + 1;}} else { // 中间元素在原来最小元素和现在最右边元素之间// 如果目标值<=最后一个元素 && 目标值>中间元素// 说明目标值在中间元素和最后一个元素之间(这部分是有序的),左索引=mid+1if (nums[n-1] >= target && target > nums[mid]) {left = mid + 1;} else {// 否则说明目标值在中间元素和最后一个元素之间,左索引=mid+1right = mid -1;}}}return -1;}
}

复杂度

  • 时间复杂度:O(log(n)),其中 n 是数组长度
  • 空间复杂度:O(1)
http://www.lryc.cn/news/274481.html

相关文章:

  • 分类预测 | Python实现基于SVM-RFE-LSTM的特征选择算法结合LSTM神经网络的多输入单输出分类预测
  • JetBrains Rider使用总结
  • C# Emgu.CV4.8.0读取rtsp流录制mp4可分段保存
  • java碳排放数据信息管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
  • K8S陈述式资源管理(1)
  • STL map容器与pair类模板(解决扫雷问题)
  • 【React系列】Portals、Fragment
  • ByteTrack算法流程的简单示例
  • 免费的GPT4来了,你还不知道吗?
  • win10报错“zlib.dll文件丢失,软件无法启动”,修复方法,亲测有效
  • MFC中如何使用CListCtrl可以编辑,并添加鼠标右键及双击事件。
  • [每周一更]-(第81期):PS抠图流程(扭扭曲曲的身份证修正)
  • Kafka安全认证机制详解之SASL_PLAIN
  • 2023南京理工大学通信工程818信号系统及数电考试大纲
  • wsl(ubuntu)创建用户
  • [足式机器人]Part2 Dr. CAN学习笔记-自动控制原理Ch1-8Lag Compensator滞后补偿器
  • swift-碰到的问题
  • 安全与认证Week4
  • Golang高质量编程与性能调优实战
  • vite 如何打包 dist 文件到 zip 使用插件 vite-plugin-zip-pack,vue3 ts
  • jdbc源码研究
  • 挠性及刚挠结合印制电路技术
  • Python+OpenGL绘制3D模型(七)制作3dsmax导出插件
  • MediaPipeUnityPlugin Win10环境搭建(22年3月的记录,新版本已完全不同,这里只做记录)
  • Nginx - location块中的alias和try_files重定向
  • 二刷Laravel 教程(用户模型)总结Ⅲ
  • 安装PyTorch及环境配置(应用于Python上的YOLO)
  • 【194】PostgreSQL 14.5 编写SQL从身份证号中查找性别,并且更新性别字段。
  • 微服务管家:NestJS 如何使用服务发现 Consul 实现高效的微服务节点管理
  • Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为Mat图像格式(C++)