[剑指Offer]11-旋转数组的最小数字(二分查找)
题目链接
题意
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
解题思路
使用二分查找思想,可以将时间复杂度由O(n)优化到O(logn)。
旋转数组特点:
- 由左右两个有序数组组成,左边的数组元素都大于等于右边的数组元素,要找的最小元素是右边数组的第一个。
- 可以采用二分法,拿中间元素与左右两端元素比较,若大于等于l,则中间元素属于左数组,令l=mid;若小于等于r,则中间元素属于右数组,令r=mid。
- 最终,将l=r-1,而最小元素即为r所指元素,这是终止条件。
二刷解题思路更新
- 还是用原始二分的初始化l=0;r=arr.length-1;
- 但是while条件是l<r-1保证l=r-1是结束,返回r即可。此外,mid=r;mid=l。保证l一直在左区间,r一直在右区间。
考虑特例:
- 特例1 左旋转为前0个,此时最小元素为第一个,要单独判断这种情况。
- 特例2 l r mid 三个指向的元素相同,此时无法判断mid要归在左边还是右边,进而影响最终的结果,所以这种情况只能使用顺序查找。
相关知识
二分查找的思考:
- 二分查找方法的关键是用数组中间的元素与某些东西比较,达到每次减少一半范围的效果,以将查找复杂度优化到O(logn)。
- 大部分题目使用二分是在“有序”的情景下,但是无序也可以使用二分,只要能确定二分的某一侧肯定有要找的内容即可。
代码(C++)
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if (rotateArray.size() == 0) {
return 0;
}
else if (rotateArray.size() == 1) {
return rotateArray[0];
}
else{
size_t l = 0;
size_t r = rotateArray.size() - 1;
if (rotateArray[l] < rotateArray[r]) {//特例1 旋转左边0个
return rotateArray[l];
}
size_t mid;
while (l != r - 1) {
mid = (l + r) / 2;
if (rotateArray[l] == rotateArray[r] && mid == rotateArray[l]) {//特例2 三者相等,无法判断mid指向的元素属于左边的有序数组还是右边的有序数组,此时只能采用顺序查找
break;
}
if (rotateArray[mid] >= rotateArray[l]) {
l = mid;
}
else if (rotateArray[mid] <= rotateArray[r]) {
r = mid;
}
}
if (l != r - 1) {//顺序查找
int min = rotateArray[0];
for (int i = 1;i < rotateArray.size();++i) {
if (rotateArray[i] < min) {
min = rotateArray[i];
}
}
return min;
}
else {
return rotateArray[r];
}
}
}
};
代码(Java)
public class Solution {
public int minNumberInRotateArray(int[] array) {
if (array.length == 0) {
return 0;
} else if (array.length == 1) {
return array[0];
} else {
int l = 0;
int r = array.length - 1;
if (array[l] < array[r]) {// 旋转0
return array[l];
}
while (l < r - 1) {
int mid = (l + r) >> 1;
if (array[l] == array[mid] && array[mid] == array[r]) {
break;
}
if (array[mid] >= array[l]) {
l = mid;
}
else if (array[mid] <= array[r]) {
r = mid;
}
}
int min;
if (l != r - 1) {// 使用循环查找
min = Integer.MAX_VALUE;
for (int i = 0; i < array.length; ++i) {
if (array[i] < min) {
min = array[i];
}
}
} else {
min = array[r];
}
return min;
}
}
[剑指Offer]11-旋转数组的最小数字(二分查找)的更多相关文章
- ⛅剑指 Offer 11. 旋转数组的最小数字
20207.22 LeetCode 剑指 Offer 11. 旋转数组的最小数字 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小 ...
- [剑指 Offer 11. 旋转数组的最小数字]
[剑指 Offer 11. 旋转数组的最小数字] 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如,数组 [3,4,5, ...
- 剑指Offer:旋转数组的最小数字【11】
剑指Offer:旋转数组的最小数字[11] 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4 ...
- 【Java】 剑指offer(10) 旋转数组的最小数字
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. ...
- 剑指offer——11旋转数组中最小的数字
题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转 ...
- Go语言实现:【剑指offer】旋转数组的最小数字
该题目来源于牛客网<剑指offer>专题. 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3, ...
- 剑指OFFER之旋转数组的最小数字(九度OJ1386)
题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转 ...
- 剑指Offer 6. 旋转数组的最小数字 (数组)
题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋 ...
- 《剑指offer》-旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数 ...
- 剑指offer例题——旋转数组的最小数字
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转, ...
随机推荐
- WPF 自定义鼠标光标
在程序中使用自定义鼠标光标的三种方式: RadioButton senderButton = sender as RadioButton; 方式一: str ...
- 07-border(边框)
边框 边框有三个要素: 粗细.线性样式.颜色 border: solid 如果颜色不写,默认是黑色. 如果粗细不写,不显示边框. 如果只写线性样式,默认的有上下左右 3px的宽度,实体样式,并且黑色的 ...
- jsfl 常用方法
//打开fla文档 fl.openDocument (JSFL_PATH+"tongzhi.fla"); //发布flash fl.getDocumentDOM().publish ...
- JSONArray 遍历
JSONArray 遍历 刚遇到一个接接口任务,发现其中返回数据中,是个字符串数组,数组中就是单个json形式的内容,其实应该也可以称这种数据叫做json数组吧,只不过是字符串形式.而我需要的是将 ...
- SRM-相关资料路径
SRM采购管理平台功能介绍 https://wenku.baidu.com/view/b05cff5930b765ce0508763231126edb6f1a763c.html https://wen ...
- U3D MemoryProfiler
MemoryProfiler Unity 5.3a4 has a new very lowlevel memory profiler API. It can tell you which object ...
- [PHP]PHP自定义遍历目录下所有文件的方法
header('content-type:text/html;charset=utf-8');/** * 方法一:使用readir()遍历目录 */function listDir($dir){ ...
- 中文转码器的工作原理_delphi教程
最近在做Delphi下的简体与繁体转换, 发现Windows2000自带的工具"中文转码器"很好用, 不仅可以转内码(BIG5-->GBK), 还可以将繁体字转为简体字(如: ...
- 16.3 authguard 通过routing path控制显示URL 通过ngif显示和隐藏
显示或者隐藏component 通常情况下 我们的做法是把它做成class 以上两步完成,我们就可以用service了,再此之前,我们先 这样弄完以后 . 非登录状态键入上面地址会自动返回下面的地址 ...
- ArcGIS案例学习笔记4_1_矢量校正
ArcGIS案例学习笔记4_1_矢量校正 概述 计划时间:第四天上午 教程:Editing编辑教程 pdf 目的:矢量数据的空间校正 案例1:仿射变换 数据:Editing编辑数据/spatialAd ...