11、旋转数组的最小数字
旋转数组的概念:
把一个数组最开始的若干个元素搬到数组的末尾,就是旋转数组。
例如: 数组{1,2,3,4,5}的一个旋转数组就是{3,4,5,1,2},把1,2放数组的后面。
题目:
- 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素
思路:
这题最直观的解答就是遍历一遍数组,直接找出其中最小的元素。时间复杂度是O(n)。但是没有利用旋转数组的特性。
我们可以再来看看旋转数组:
旋转数组的特性:
- 可以拆分为两个排好序的子数组
- 前面的子数组的元素大于或者等于后面子数组的元素。
- 最小的数组恰好是这两个数组的分界线。
举例说明:
旋转数组在一定程度上是排序的,因此试试用二分法找最小的元素。
直接举例说明,
我们以数组{3,4,5,1,2},指定两个指针,一个指向第一个元素3,一个指向最后一个元素2,如下图所示。位于两个指针中间的元素是5,它大于第一个指针指向的元素。因此中间数字5一定是前面的递增子数组中的元素,故最小的元素一定位于它的后面。所以移动第一个指针指向中间,如图所示,缩小查询范围。
这时,位于两个指针中间的元素是1,1小于第一个指针指向的元素,所以数字1位于后面的递增子数组中,故最小元素在数字1的前面或者就是数字1,这时将第二个指针指向数字1,缩小查询范围,如图所示。
此时,两个指针的距离是1,所欲第一个指针指向的是前面的递增子数组的最后一个元素,即最大的元素;第二个指针指向的是后面的递增子数组中第一个元素,即最小的元素,这就找到了。
代码(继续看下去)
def MinInOrder(array):if array == None or len(array) <= 0: # 排除空集return falsel = 0 # 定义左指针r = len(array) - 1 # 定义右指针while(array[l] >= array[r]): if r - l == 1: # 当左右指针相邻时,说明找到了,右指针指向的就是最小的元素return array[r]breakmid = l + ((r - l) >> 1) # mid是中间元素的indexif array[mid] > array[l]: # 若中间元素大于左指针指向的元素,说明最小元素在其后,故缩小查询范围l = midelse: # 反之同理r = midreturn array[mid]
输入:
array = [3,4,5,1,2]
MinInOrder(array)
输出:1
别急,还没有完,其实还有两个问题没考虑到
问题一:
前面说旋转数组是把前面部分元素搬到后面去,这没错,但是有个特殊情况,那就是我把前面0个元素搬到后面去,即旋转数组还是自己本身,哈哈哈,是不是有意思了。
这个时候,数组中最小的元素就是第一个元素了,我们试着运行上的代码:
输入:
array = [1,2,3,4,5]
MinInOrder(array)
输出:5
看见没有。输出的是5,最大的元素找出来,但我们要的是最小的元素,所以我们得改改代码
问题二:
看个例子,数组{0,1,1,1,1} 现在有两个旋转数组 {1,0,1,1,1} 和数组 {1,1,1,0,1}
看上图,会发现,左右指针指向的元素和中间元素是一样,这个时候,就不知道中间元素到底是前面的递增子数组还是后面的递增子数组,所以无法缩小查找范围。这时我们就得采用顺序查找的方式了。看完整的代码:
class Solution:def Min(self,array):if array == None or len(array) <= 0: # 排除空集return Falsel = 0 # 定义左指针r = len(array) - 1 # 定义右指针mid = 0 # 将指针mid初始为0,一旦发现数组第一个元素小于最后一个元素,即数组是排序的(问题一),这直接返回while(array[l] >= array[r]): if r - l == 1: # 当左右指针相邻时,说明找到了,右指针指向的就是最小的元素return array[r]breakmid = l + ((r - l) >> 1) # mid是中间元素的index# 如果左指针、右指针指向的元素和中间元素一致时(问题二),采用顺序查找if array[l] == array[mid] == array[r]:return self.MinOrder(array,l,r)if array[mid] > array[l]: # 若中间元素大于左指针指向的元素,说明最小元素在其后,故缩小查询范围l = midelse: # 反之同理r = mid# 如果左指针、右指针指向的元素和中间元素一样,则只能顺序查找return array[mid]def MinOrder(self,array,l,r): # 顺序查找,循环遍历所有元素,找最小的元素re = array[l]for i in range(l+1,r):if re > array[i]:re = array[i]return reif __name__ == "__main__":# 验证# 功能测试:输入数组升序数组的一个旋转数组,数组中有重复或在没有重复的数字test1 = [3,4,5,1,2]test2 = [1,0,1,1,1]# 边界测试:输入数组只有一个元素test3 = [5]# 特在测试:输入数组是空test4 = []solution = Solution()print("test_1:", solution.Min(test1))print("test_2:", solution.Min(test2))print("test_3:", solution.Min(test3))print("test_4:", solution.Min(test4))
输出:
test_1: 1
test_2: 0
test_3: 5
test_4: None
简写
def minNumberInRotateArray(rotateArray):# write code here# 二分查找:找左右的方法:右边的值大于中指时,说明最小值在左边,反之if rotateArray == None: # 排除空集return 0left = 0 # 定义左指针right = len(rotateArray) -1 # 定义右指针while left <= right:mid = (right + left) >> 1 # 定义中间指针if rotateArray[mid] < rotateArray[mid-1]: # 若中间指针对应的元素恰好小于前一个元素,说明当前元素就是最小的元素return rotateArray[mid]elif rotateArray[mid] < rotateArray[right]: # 若中间元素小于最右边的元素,说明最小值在左边,更新指针right = mid-1else: # 反之left = mid+1return 0
11、旋转数组的最小数字相关推荐
- 《LeetCode力扣练习》剑指 Offer 11. 旋转数组的最小数字 Java
<LeetCode力扣练习>剑指 Offer 11. 旋转数组的最小数字 Java 一.资源 题目: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 给你一个可能存在 ...
- 剑指 Offer 11. 旋转数组的最小数字 简单
剑指 Offer 11. 旋转数组的最小数字 题目 解题思路 方法(一)直接遍历法 方法(二)二分查找法 题目 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组 ...
- LeetCode-剑指 Offer 11. 旋转数组的最小数字
剑指 Offer 11. 旋转数组的最小数字 思路一:先排序,返回第一个数组值 class Solution {public:int minArray(vector<int>& n ...
- 剑指offer 11. 旋转数组的最小数字(很详细!)
剑指offer 11. 旋转数组的最小数字 题目 解题思路 代码 题目 解题思路 一开始,我们就能直接想到,数组找最小值,那么不轻轻松松直接遍历一遍,用一个变量记录最小值,然后直接返回不就完事了? 但 ...
- 【LeetCode】剑指 Offer 11. 旋转数组的最小数字
[LeetCode]剑指 Offer 11. 旋转数组的最小数字 文章目录 [LeetCode]剑指 Offer 11. 旋转数组的最小数字 一.遍历 二.二分法 总结 一.遍历 算法步骤: 遍历数组 ...
- 【剑指 Offe】11. 旋转数组的最小数字
题目:剑指 Offer 11. 旋转数组的最小数字 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数 ...
- 【剑指 Offe】剑指 Offer 11. 旋转数组的最小数字
目录标题 算法汇总 题目 关键点 代码 1.解体方法 - 二分法 思路 代码 时间和空间复杂度 2.解题方法,如暴力法 思路 代码 时间和空间复杂度 算法汇总 以下是所有算法汇总,包括GitHub源码 ...
- 11. 旋转数组的最小数字(剑指 Offer 题解Java版)
文章目录 11. 旋转数组的最小数字 题目描述 题目链接 解题思路 可以借助下图理解过程 代码 11. 旋转数组的最小数字 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. ...
- 剑指offer:面试题11. 旋转数组的最小数字
题目:旋转数组的最小数字 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如,数组 [3,4,5,1,2] 为 [1,2, ...
- 剑指offer——11.旋转数组的最小数字
题目: 题1:实现快速排序 题2:年龄排序问题. 题3:旋转数组的最小数字 知识点: 快速排序算法,参考:https://blog.csdn.net/shujuelin/article/details ...
最新文章
- PCL:PCLPlotter可视化特征直方图
- 【Maven实战】之基础知识点
- Go 语言编程 — 使用 delve 进行 DEBUG 调试
- 【Kafka】Kafka为什么要加入分区的概念
- mongodb 查询 mysql_MongoDB 基本查询使用
- vnc--centos 7 安装和配置
- HDU4577(2013年ACM杭州赛区邀请赛B题)
- arm qt5 iconv 问题
- 90TB显存!英伟达发布新一代SuperPod超算,AI算力新巅峰!
- SSH:hql语句传参报错,及antlr-2.7.2.jar重复包的删除
- Ubuntu中anaconda的安装及使用
- 第二课--C语言基础(1,2部分--共三部分)
- 猫眼(门镜)中的光学
- Linear-chain CRF的推导
- 高效管理MacOS中文件的技巧
- python 成语库_Python“Every Other Element”成语
- 高通qxdm抓取sensor的log【学习笔记】
- 汇编语言与微机接口——交通灯设计
- 吕广渝:上帝视角看公司运营
- python中forward(200)什么意思_Python中的Phyllotaxis模式| 算法植物学的一个单位
热门文章
- “后T+0”时代:基金电商人以变应变
- (转)谭志勇、赵微:区块链技术在中国商品交易市场的应用与发展
- 阿里集团公布2022“研究型实习生”计划
- 陈绪:7月24日阿里云上海峰会出品人
- c语言怎样用vc绘图,大佬们,小菜鸟想问一问用vc编译器做简易画图软件
- 【扩频通信】基于matlab GUI扩频通信系统仿真(带面板)【含Matlab源码 1587期】
- 【图像提取】基于matlab DNA编解码多尺度形态学提取眼前节组织【含Matlab源码 1191期】
- 【车间调度】基于matlab粒子群算法求解生产调度问题【含Matlab源码 485期】
- 【多目标优化求解】基于matlab金鹰算法求解多目标优化问题【含Matlab源码 188期】
- DeepStyle(第2部分):时尚GAN