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

力扣hot100:搜索旋转排序数组和寻找旋转排序数组中的最小值(33,153)

搜索旋转排序数组:二分查找的巧妙应用

今天我在LeetCode上解决了"搜索旋转排序数组"这个问题(题目编号33)。下面我将分享我的解题思路和代码实现。

解题思路

虽然数组被旋转了,但它仍然部分有序,这提示我们可以使用二分查找的变种来解决这个问题。关键在于如何判断目标值位于哪一部分。

  1. 常规二分查找:首先计算中间索引mid
  2. 判断有序部分
    • 如果nums[left] <= nums[mid],说明左半部分是有序的
    • 否则,右半部分是有序的
  3. 在有序部分中判断目标值的位置
    • 如果在有序部分范围内,则在该部分继续搜索
    • 否则,在另一部分搜索

代码实现

class Solution {public int search(int[] nums, int target) {int left=0;int right=nums.length-1;while(left<=right){int mid=(right-left)/2+left;if(nums[mid]==target){return mid;}if(nums[0]<=nums[mid]){//说明在左部分if(nums[left]<=target&&target<nums[mid]){right=mid-1;}else{left=mid+1;}}else{//说明在右部分if(nums[mid]<target&&target<=nums[right]){left=mid+1;}else{right=mid-1;}}}return -1;}
}

关键点解析

  1. 边界条件处理:使用left <= right作为循环条件,确保所有元素都被检查。
  2. 防止整数溢出:计算mid时使用(right - left) / 2 + left而不是(left + right) / 2
  3. 有序部分判断:通过比较numsnums[mid]来确定哪一部分是有序的。
  4. 目标值范围判断:在确定有序部分后,检查目标值是否在该部分范围内,以决定搜索方向。

复杂度分析

  • 时间复杂度:O(log n),因为每次都将搜索范围减半。
  • 空间复杂度:O(1),只使用了常数级别的额外空间。

=========================================================================

寻找旋转排序数组中的最小值:二分查找的精妙应用

解题思路

旋转后的数组虽然不再是完全有序,但仍然保持部分有序的特性,这使得我们可以使用二分查找算法高效解决:

  1. 理解旋转特性:旋转后的数组分为两个有序部分,最小值位于两个有序部分的交界处
  2. 二分查找的关键
    • 比较中间元素和右边界元素
    • 如果中间元素小于右边界元素,说明最小值在左半部分(包括中间元素)
    • 如果中间元素大于右边界元素,说明最小值在右半部分(不包括中间元素)
  3. 循环终止条件:当左指针和右指针相遇时,它们指向的位置就是最小值

代码实现

class Solution {public int findMin(int[] nums) {int left=0;int right=nums.length-1;//当使用 left < right 作为循环条件时,循环结束时 left 和 right 指向同一个位置,而这个位置就是我们要找的目标while(left<right){int mid=(right-left)/2+left;if(nums[mid]<=nums[right]){right=mid;}else if(nums[mid]>=nums[right]){left=mid+1;}}//当 nums[mid] > nums[right] 时,说明最小值在右半部分,且 mid 位置肯定不是最小值,所以应该设置 left = mid + 1//当 nums[mid] < nums[right] 时,说明最小值在左半部分,且 mid 位置可能是最小值,所以应该设置 right = midreturn nums[left];}
}

关键点解析

  1. 循环条件选择:使用left < right而不是left <= right,确保最终left和right会相遇
  2. 边界处理
    • nums[mid] <= nums[right]时,最小值在左半部分(包括mid)
    • nums[mid] > nums[right]时,最小值在右半部分(不包括mid)
  3. 指针移动逻辑
    • 最小值在左侧时:right = mid(mid可能是最小值)
    • 最小值在右侧时:left = mid + 1(mid不可能是最小值)
  4. 终止条件:当left == right时,指向的就是最小值

复杂度分析

  • 时间复杂度:O(log n),每次迭代都将搜索范围减半
  • 空间复杂度:O(1),只使用了常数级别的额外空间

实例演示

假设输入数组为[4,5,6,7,0,1,2]

  1. 初始:left=0, right=6, mid=3 (值为7)
    • 7 > 2 → 最小值在右侧 → left=mid+1=4
  2. 第二轮:left=4, right=6, mid=5 (值为1)
    • 1 <= 2 → 最小值在左侧 → right=5
  3. 第三轮:left=4, right=5, mid=4 (值为0)
    • 0 <= 1 → 最小值在左侧 → right=4
  4. 循环结束:left=4, right=4 → 返回nums=0

总结

这道题目展示了二分查找算法的强大适应能力。即使数组不是完全有序,通过巧妙地比较中间元素与边界元素的关系,我们仍然可以在对数时间内找到最小值。这种思路在实际应用中非常有用,特别是在处理部分有序或旋转后的数据时。

关键启示:

  1. 理解旋转数组的特性:由两个有序部分组成
  2. 通过比较中间元素和边界元素确定最小值的位置
  3. 精心设计的指针移动逻辑确保高效搜索

掌握了这种二分查找的变种,我们能够解决更多类似的搜索问题,提高算法解决实际问题的能力。

http://www.xdnf.cn/news/18995.html

相关文章:

  • TikTok广告投放革命:指纹云手机如何实现智能群控与降本增效
  • Mac中修改Word的Normal.dotm文件
  • CSS实现内凹圆角边框技巧(高频)
  • 绿算技术解密金融科技安全:高性能计算与存储驱动金融防火墙新时代
  • 【拥抱AI】一起学卷积神经网络(CNN)
  • 一天推荐一款实用的手柄零件————线性霍尔
  • Zynq开发实践(FPGA之verilog仿真)
  • Flask 之上下文详解:从原理到实战
  • OSG+Qt —— 笔记3- Qt窗口绘制模型的三条轴(附源码)
  • 【Linux操作系统】简学深悟启示录:环境变量进程地址
  • Mysql面试题分享
  • 医疗巡诊车5G专网路由器应用
  • webrtc音频QOS方法一.1(NetEQ之音频网络延时DelayManager计算补充)
  • Spring Boot 与传统 Spring:从 WAR 到可执行 JAR,颠覆性的部署哲学
  • 在 TencentOS 3 上部署 OpenTenBase:从底层原理到生产级实践的深度指南
  • 微服务-24.网关登录校验-实现登录校验
  • 网站开发用什么语言好
  • 数据结构:链式队列尝试;0826
  • 庖丁解牛:深入解析Oracle SQL语言的四大分类——DML、DDL、DCL、TCL
  • Rust 环境搭建与 SeekStorm 项目编译部署(支持中文)
  • Redis相关命令详解及其原理
  • MT** 时间指标全景图:从可靠性到可维护性的度量体系
  • LangGraph-2-Demo
  • CI/CD 全链路实践:从 Git 基础到 Jenkins + GitLab 企业级部署
  • Python 操作 PPT 文件:从新手到高手的实战指南
  • 线性代数中矩阵等价与离散数学中关系的闭包之间的关联
  • VScode,设置自动保存
  • Vue中的props方式
  • 多模态RAG架构:下一代跨模态智能检索系统的设计与实践
  • 视频合成素材视频-多合一功能-青柠剪吧