[剑指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}的一个旋转, ...
随机推荐
- smarty获取php中的变量
{$smarty}保留变量不需要从PHP脚本中分配,是可以在模板中直接访问的数组类型变量,通常被用于访问一些特殊的模板变量.例如,直接在模板中访问页面请求变量.获取访问模板时的时间邮戳.直接访问PHP ...
- Django权限auth模块详解
转自:http://www.cnblogs.com/Finley/p/5575305.html 1,auth模块是Django提供的标准权限管理系统,可以提供用户身份认证,用户组和权限管理 2,aut ...
- Python 百分号字符串拼接
# %s可以接收一切 %d只能接收数字 msg = 'i am %s my hobby is %s' %('lhf','alex') print msg msg2 = 'i am %s my hobb ...
- iOS开发 2x 3x图
众所周知,iOS开发中的图片资源一般需要2倍图和3倍图,也就是2x,3x,但是最近思考了一个问题,为什么不能只提供3x的图片,2x的图片让系统从3x压缩就好了,于是上网搜索了下,得到了答案. 当我们在 ...
- Delphi Locate 详解1 转
TDataSet控件以及它的继承控件,例如TSimpleDataSet/TClientDataSet等都可以使用Locate方法在结果数据集中查寻数据.程序首先必须使用SQL命令从后端数据库中取得数据 ...
- Indy 10.5.8 for Delphi and Lazarus 修改版(2011)
Indy 10.5.8 for Delphi and Lazarus 修改版(2011) Internet Direct(Indy)是一组开放源代码的Internet组件,涵盖了几乎所有流行的I ...
- [ SHELL编程 ] shell编程中数值计算方法实例
SHELL编程中经常会涉及到数值计算,有时候对于这些计算命令使用场景容易忘记或者混淆,这里针对常用的命令做个总结.主要包括let.bc.expr.(())等. 1.let 使用格式:let 表达式,表 ...
- [C语言]变量VS常量
-------------------------------------------------------------------------------------------- 1. 固定不变 ...
- HBase 1.2.6 完全分布式集群安装部署详细过程
Apache HBase 是一个高可靠性.高性能.面向列.可伸缩的分布式存储系统,是NoSQL数据库,基于Google Bigtable思想的开源实现,可在廉价的PC Server上搭建大规模结构化存 ...
- redis集群实战
一.说明 redis 3.0集群功能出来已经有一段时间了,目前最新稳定版是3.0.5,我了解到已经有很多互联网公司在生产环境使用,比如唯品会.美团等等,刚好公司有个新项目,预估的量单机redis无法满 ...