本文参考自《剑指offer》一书,代码采用Java语言。

更多:《剑指Offer》Java实现合集  

题目

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

思路

  数组在一定程度上是排序的,很容易分析出:可以采用二分法来寻找最小数字。

  但是这里面有一些陷阱:

  1.递增排序数组的本身是自己的旋转,则最小数字是第一个数字

  2.中间数字与首尾数字大小相等,如{1,0,1,1,1,1}和{1,1,1,1,0,1},无法采用二分法,只能顺序查找。

测试用例

  1.功能测试(正常旋转数组,中间有或者无重复数字)

  2.边界值测试(升序数组,1个数字的数组)

  3.特殊输入测试(null,空数组)

完整Java代码

(含测试代码)

/**
*
* @Description 旋转数组的最小数字
*
* @author yongh
* @date 2018年9月14日 下午8:30:29
*/ // 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
// 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组
// {3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。 public class MinNumberInRotatedArray {
public int minNumberInRotateArray(int[] array) {
if (array == null || array.length <= 0) // 空数组或null时返回0
return 0;
int low = 0;
int high = array.length - 1;
int mid = (low + high) / 2;
//升序数组
if (array[low] < array[high])
return array[low];
//中间数字与首尾数字相等
if (array[mid] == array[high] && array[mid] == array[low]) {
for (int i = 1; i <= high; i++) {
if (array[i] < array[i - 1])
return array[i];
}
return array[low];
}
//正常情况
while (low < high) {
if (high - low == 1)
break;
mid = (low + high) / 2;
if (array[mid] <= array[high])
high = mid;
if (array[mid] > array[high])
low = mid;
}
return array[high]; // 别错写成了return high; !!
} // =======测试代码======
public void test1() {
int[] array = null;
System.out.println("test1:" + minNumberInRotateArray(array));
} public void test2() {
int[] array = {};
System.out.println("test2:" + minNumberInRotateArray(array));
} public void test3() {
int[] array = { 1 };
System.out.println("test3:" + minNumberInRotateArray(array));
} public void test4() {
int[] array = { 1, 2, 3, 4, 5, 6 };
System.out.println("test4:" + minNumberInRotateArray(array));
} public void test5() {
int[] array = { 2, 2, 2, 2, 1, 2 };
System.out.println("test5:" + minNumberInRotateArray(array));
} public void test6() {
int[] array = { 2, 1, 2, 2, 2, 2 };
System.out.println("test6:" + minNumberInRotateArray(array));
} public void test7() {
int[] array = { 6, 6, 8, 9, 10, 1, 2, 2, 3, 3, 4, 5, 6 };
System.out.println("test7:" + minNumberInRotateArray(array));
} public static void main(String[] args) {
MinNumberInRotatedArray demo = new MinNumberInRotatedArray();
demo.test1();
demo.test2();
demo.test3();
demo.test4();
demo.test5();
demo.test6();
demo.test7();
}
}

  

test1:
test2:
test3:
test4:
test5:
test6:
test7:

MinNumberInRotatedArray

代码学习

  下面的代码是牛客网中的FINACK写的代码,非常简略。在保证可读性的情况下,希望自己也能早日写出简洁高效的代码。

public class Solution {
public int minNumberInRotateArray(int [] array) {
int low = 0 ; int high = array.length - 1;
while(low < high){
int mid = low + (high - low) / 2;
if(array[mid] > array[high]){
low = mid + 1;
}else if(array[mid] == array[high]){
high = high - 1;
}else{
high = mid;
}
}
return array[low];
}
}

  注意这段代码的一些细节:

  1.使用low=mid+1,而不是low=mid,最终会使得low=high(即最小值位置)而跳出循环;

  2.使用high=mid,而不是high=mid-1,因为有可能mid就是最小值点,不能减1;

  3.升序数组的情况可以直接在循环中一起搞定,不用单独列出来判断(自己的代码还可以改进)

  小瑕疵:

  1.该程序在array[mid] = array[high]时直接顺序查找。但其实这还有可能可以用二分法的,除非还满足array[mid] = array[low],才只能使用顺序查找。所以可以先排除掉必须顺序查找的情况(类似自己上面的程序,提前判断掉),之后就可以直接删除else if(array[mid] == array[high]){high = high - 1;这两行了。

  2.缺少null的判断。

收获

  1.对于一些涉及数组的方法(如二分法等),可以用low和high,mid等来定义下标,但是,输出时如果要求输出数据值array[low],不要错写成下标low了。

  2.思维一定要考虑全面,特别是接触到一个新的概念时,要注意到一些特例,如递增排序数组的本身是自己的旋转、相同数字数组等。

更多:《剑指Offer》Java实现合集  

【Java】 剑指offer(10) 旋转数组的最小数字的更多相关文章

  1. [剑指offer] 10. 旋转数组的最小数字

    题目描述 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 思路: 利用dp[i]保存盖2*i的矩形有多少种办法. 通过 ...

  2. 剑指Offer:旋转数组的最小数字【11】

    剑指Offer:旋转数组的最小数字[11] 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4 ...

  3. ⛅剑指 Offer 11. 旋转数组的最小数字

    20207.22 LeetCode 剑指 Offer 11. 旋转数组的最小数字 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小 ...

  4. [剑指 Offer 11. 旋转数组的最小数字]

    [剑指 Offer 11. 旋转数组的最小数字] 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如,数组 [3,4,5, ...

  5. Go语言实现:【剑指offer】旋转数组的最小数字

    该题目来源于牛客网<剑指offer>专题. 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3, ...

  6. 剑指offer例题——旋转数组的最小数字

    题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转, ...

  7. 剑指OFFER之旋转数组的最小数字(九度OJ1386)

    题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转 ...

  8. 剑指Offer 6. 旋转数组的最小数字 (数组)

    题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋 ...

  9. 《剑指offer》-旋转数组的最小数字

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

随机推荐

  1. mipsel汇编指令学习

    MIPS汇编语言基础 MIPS的系统结构及设计理念比较先进,其指令系统经过通用处理器指令体系MIPS I.MIPS II.MIPS III.MIPS IV.MIPS V,以及嵌入式指令体系MIPS16 ...

  2. QMouseEvent鼠标事件

    Qt中的QMouseEvent一般只涉及鼠标左键或右键的单击.释放等操作,而对鼠标滚轮的响应则通过QWheeEvent来处理

  3. P3806 【模板】点分治1(CDQ分治)

    题目链接:https://www.luogu.org/problemnew/show/P3806 题目大意:中文题目 具体思路:直接dfs好像会超时,然后我们就开始想优化的方法,然后就是一个CDQ入门 ...

  4. 使用CSS将图像对齐

    相对于<img>元素的align特性来说,越来越多的网页设计人员使用float属性来对齐图像.可以采用两种方式来实现对齐.为了确保文本不会与图像的边缘接触,我们经常会给图像增加一个外边距. ...

  5. Django学习手册 - 模板继承与导入

    核心: PS:一个页面只能继承一个模板. 前置: 配置url. 配置views 关键字: 1. {% extends "index模板.html" %} 声明继承于哪个模板 ,关联 ...

  6. npm快捷键

    一.npm基本快捷键 node -v查看安装的nodejs版本,出现版本号,说明刚刚已正确安装nodejs.PS:未能出现版本号,请尝试注销电脑重试: npm -v查看npm的版本号,npm是在安装n ...

  7. layoutSubviews总结(转)

    - (void)setNeedsDisplay - (void)drawRect 但是是用initWithFrame 进行初始化时,当rect的值不为CGRectZero时,也会触发 You shou ...

  8. 【转】Python之装饰器

    [转]Python之装饰器 本节内容 必要知识回顾 情景模拟 装饰器的概念及实现原理 回马枪(带参数的装饰器) 一. 必要知识回顾 在开始说装饰器之前,需要大家熟悉之前说过的相关知识点: 函数即“变量 ...

  9. sqlserver数据库系统性能监控步骤

    1.部署好环境JDK+tomcat+数据库 ①修改数据库连接账号密码db.properties ②修改applicationContext.xml文件,开启任务 <bean id="o ...

  10. js学习、备忘

    字符串使用单引号’abc’.(双引号也行.推荐:html→双引号,js→单引号)===严格等于.!==严格不等于if(x)  当x为undefined.null和0的时候都为false:需注意当x为0 ...