剑指 Offer 11. 旋转数组的最小数字 - leetcode 剑指offer系列
发布日期:2021-06-29 07:11:49 浏览次数:3 分类:技术文章

本文共 2442 字,大约阅读时间需要 8 分钟。

题目难度: 简单

今天继续更新剑指 offer 系列, 这道题能帮助我们更好地理解二分查找, 很值得一做. 另外基于它还能解决一些进阶问题, 例如, 在最后面我也会说下那道题的思路, 也有对应的题解链接, 感兴趣的同学也可以自己试试哦

若无意外, 每天晚上 6 点 45 分准时更新, 中间可能会穿插一些周赛题解. 大家在我的公众号"每日精选算法题"中的聊天框中回复 offer 就能看到该系列当前已经更新的文章了

大家有什么想法建议和反馈的话欢迎随时交流, 包括但不限于公众号聊天框/知乎私信评论等等~

题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组  [3,4,5,1,2][1,2,3,4,5] 的一个旋转,该数组的最小值为 1。

题目样例

示例 1

输入

[3,4,5,1,2]

输出

1

示例 2

输入

[2,2,2,0,1]

输出

0

题目思考

  1. 如果利用原始数组有序这一条件?

解决方案

思路

分析

  • 直接利用 min 或者遍历一遍求最小值也能得到结果, 但这完全没有用上原始数组有序这一条件, 所以也不是这道题目考察的本意所在
  • 而数组有序一般就可以尝试二分查找来加速运算, 这道题也不例外
  • 因为进行过旋转, 所以数组最多可能会有两段递增的区间, 而它们的分界点就是旋转点(当然也有可能旋转 0 个数字, 那就是自身一段递增区间)
  • 基于经典二分查找, 考虑中间下标 m 对应的数字:
    1. 如果中间值小于末尾, 那么一定说明该数字之后(后半段)有序.
      • 这里可以用反证法证明: 假设此时后半段无序, 意味着分界点就在后半段, 那么前半段一定有序, 也即中间值大于等于开头, 而分界点又是原数组起点, 它在后半段, 这就意味着开头一定大于等于末尾, 综合起来就是中间值大于等于末尾, 正好与前提矛盾.
      • 后半段有序, 那么最小值一定是中间值或者更前面, 所以二分进入前半段即可, 注意需要保留 m 作为候选项
    2. 如果中间值大于末尾, 那么毫无疑问后半段无序.
      • 后半段无序, 那么一定会排除前半段. 因为根据上面的分析, 末尾此时一定小于等于开头, 开头到中间的部分都大于等于末尾, 所以二分进入右半段即可, 这里不需要保留 m 作为候选项, 因为末尾一定小于它
    3. 如果中间值等于末尾, 那就不好判断是前半段无序还是后半段无序了, 举两个例子大家就应该很清楚了: 前半段无序 [2,1,2,2,2]; 后半段无序 [2,2,2,1,2]
      • 这种情况由于无法判断有序, 只能退化成逐个遍历, 末尾-1 即可. 注意此处不能是开头+1, 因为并不确定开头和中间值的关系, 有可能开头是最小值
  • 根据上述三种情况, 每次区间缩小都会保留最小值作为候选项, 所以最后收敛到的值一定是最小值

实现

  • 经典二分查找的变种
  • 定义开头下标和结尾下标 s 和 e
  • 计算中间下标 m, 根据中间值与末尾值的关系来二分区间, 具体关系和上面分析完全一致
  • 下面代码对必要步骤都有解释, 方便大家理解

复杂度

  • 时间复杂度 O(logN)~O(N)
    • 大部分情况下 O(logN) 时间就能二分出结果, 最差情况会退化成O(N) (数组元素都相等时)
  • 空间复杂度 O(1)
    • 只需要几个变量即可

代码

class Solution:    def minArray(self, numbers: List[int]) -> int:        # 简单二分, 当m=e时无脑直接e-1...        # 最后返回跳出循环后的numbers[s]        # 注意m
> 1 if numbers[m] < numbers[e]: # m可能是最小值, 不能排除它 e = m elif numbers[m] > numbers[e]: # m一定不是最小值, 排除它 s = m + 1 else: # 退化的情况 e -= 1 return numbers[s]

进阶问题思路

  • 看到这里, 相信大家已经掌握了求旋转数组中最小数字的方法
  • 对于进阶问题, 它不是求旋转数组最小数字, 而是求目标数字在里面的最小下标, 这里为了方便大家查看, 我先把那道题的题目贴出来

搜索旋转数组。给定一个排序后的数组,包含 n 个整数,但这个数组已被旋转过很多次了,次数不详。请编写代码找出数组中的某个元素,假设数组元素原先是按升序排列的。若有多个相同元素,返回索引值最小的一个。

  • 注意进阶问题里说的是旋转多次, 但其实旋转一次和旋转多次没有任何区别, 最终还是只有一个旋转点, 以及不多于 2 个的有序区间
  • 基于这一点, 我们就可以在这两个有序区间内利用经典二分查找来找目标值, 所以问题就转化为了如何找分界点
  • 分界点一定是最小数字, 且其上一个值要大于它. 这样就可以用本题的思路, 判断 e 是不是分界点即可: 是的话直接退出循环, 否则继续二分找包含最小数字的区间.
    • 注意: 这里必须用 e 来判断分界点, 是因为用 m 的话可能会在退化情况时漏掉正确分界点, 例如[2,2,2,1,2]这个例子, 分界点是 1, 但是 m 始终不会达到 1, 而 e 则总能
  • 另外注意如果前半段找到了就没必要找后半段了, 因为要求的是最小下标
  • 对于这个进阶问题, 我也在 leetcode 上发布了一篇题解: , 里面有实现的代码, 感兴趣的同学也可以去看看~

大家可以在下面这些地方找到我~😊

我的公众号: 每日精选算法题, 欢迎大家扫码关注~😊

每日精选算法题 - 微信扫一扫关注我

转载地址:https://blog.csdn.net/zjulyx1993/article/details/106929796 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:剑指 Offer 12. 矩阵中的路径 - leetcode 剑指offer系列
下一篇:剑指 Offer 10- I. 斐波那契数列 - leetcode 剑指offer系列

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月05日 20时17分40秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

Atitit 编程语言语言规范总结 目录 1. 语言规范 3 2. Types 3 2.1.1. Primitive types 3 2.1.2. Compound types 4 3. State 2019-04-29
Atitit QL查询语言总结 目录 1. QL = Query Language, 是查询语言的简称 1 2. 具体实现 1 2.1. Apcl 流程控制语言 1 2.2. 脚本流程控制 2 2. 2019-04-29
Atitit 开发效率大法 v0 t025.docx Atitit 提升开发效率几大策略 目录 1. 提升效率三原则 3 1.1. 更少的代码量简化 3 1.2. 优化配置减少等待 3 1.3. 2019-04-29
Atitit mybatis的扩展使用sql udf,js java等语言 目录 1.1. 默认,mybatis使用xml,sql等语言来书写业务流程 1 2. 使用ognl调用java函数 1 3 2019-04-29
Atitit if else 选择决策流程ast对比 sql java 表达式类型 binaryExpression hase left and rit expr 目录 1.1. Sql 1 2019-04-29
Atitit 数据库存储引擎 目录 1.1. BLACKHOLE 黑洞引擎 1 1.2. Myisam innodb 1 1.3. Archive 档案类 1 1.4. Fed 连接引擎 2 1. 2019-04-29
Atitit sql注入的防范 目录 1.1. 检查数据类型 1 2. 有限操作DML 1 2.1. 限制执行函数黑名单机制 2 2.2. 限制执行系统sp 2 2.3. 限制数据查询语句类型,只能 2019-04-29
Atitit 自然语言与人工语言的语法构建ast的异同点 目录 1. 语言节点gaishu。。 2 1.1. 节点、函数数量大约200个 2 1.2. 关键词节点 是 有 的 3 1.3. 标识符 2019-04-29
Atitit 效率提升法细则 v3 t028.docx Atitit 提升效率细则 目录 1. 目标 2 1.1. 配置化增加扩展性 尽可能消除编译 方便增加 调整业务逻辑 2 1.2. 统一接口 2019-04-29
Atitit 工程师程序员技术级别对应表与主要特征 P1--p6 说明 类别 职称 对应技术标志 P5 高级工程师 工程师类 一般四五年 P6 资深开发 工程师类 78年经历 P7 P7 2019-04-29
paip.activex控件在WEB中使用流程与工具 2019-04-29
paip.软件及网站项目开发效率低下的思索与改进 2019-04-29
Atitit 可移植性之道attilax著 2019-04-29
paip.截屏功能流程说明 2019-04-29
Atiitt uke兼wag集团2017年度成果报告总结 attilax著 1. 组织机构进一步完善 8大首席部门 1 2. 事业部进一步完善,以及一百多个事业部了 1 3. 企业文化进一步完善 1 2019-04-29
Atititi ui之道 attilax著 v3 s11.docx 1. 概览 2 1.1. 软件设计可分为两个部分:编码设计与UI设计 2 2. 用户界面设计的三大原则是:置界面于用户的控制之下; 2019-04-29
Atitit 集团与个人的完整入口列表 attilax的完整入口 1. 集团与个人的完整入口列表 1 2. 流量入口概念 2 3. 流量入口的历史与发展 2 1.集团与个人的完整入口列表 2019-04-29
Atitit 网络编程之道 2019-04-29
Atiitt attilax掌握的前后技术放在简历里面.docx 2019-04-29
Atiitt 文档处理之道 attilax著 2019-04-29