题目链接:旋转数组的最小数字

文章目录

  • 1、题目描述
  • 2、题目分析
  • 3、代码
    • 3.1 Java代码
    • 3.2、C++代码
  • 4、总结

1、题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

2、题目分析

从头遍历到尾找到最小值这种low的方法就不说了,是个人都会!!!

旋转之后的数组实际上可以划分成两个有序的子数组:前面子数组的大小都大于后面子数组中的元素

注意到实际上最小的元素就是两个子数组的分界线。本题目给出的数组一定程度上是排序的,因此我们试着用二分查找法寻找这个最小的元素。如下图:

思路:

(1)我们用两个指针l_ndex,r_index分别指向数组的第一个元素和最后一个元素。按照题目的旋转的规则,第一个元素应该是大于最后一个元素的(没有重复的元素)。
但是如果不是旋转,第一个元素肯定小于最后一个元素。

(2)找到数组的中间元素。

如果中间元素大于第一个元素,则中间元素位于前面的递增子数组,此时最小元素位于中间元素的后面。我们可以让第一个指针l_index指向中间元素。

移动之后,第一个指针仍然位于前面的递增数组中。

如果中间元素小于第一个元素,则中间元素位于后面的递增子数组,此时最小元素位于中间元素的前面。我们可以让第二个指针right指向中间元素。

移动之后,第二个指针仍然位于后面的递增数组中。这样可以缩小寻找的范围。

比如当上图的情况,那么接下来的下一次循环过后,就是下图的样式:

(3)按照以上思路,第一个指针l_index总是指向前面递增数组的元素,第二个指针r_index总是指向后面递增的数组元素。

最终第一个指针将指向前面数组的最后一个元素,第二个指针指向后面数组中的第一个元素。

也就是说他们将指向两个相邻的元素,而第二个指针指向的刚好是最小的元素,这就是循环的结束条件。

特殊情况:

到目前为止以上思路很好的解决了没有重复数字的情况。如果有重复数字情况呢?

我们看一组例子:{1,0,1,1,1} 和 {1,1, 1,0,1} 都可以看成是非减排序的数组{0,1,1,1,1}的旋转。

这种情况下我们无法继续二分法,去解决这道题目。因为在这两个数组中,第一个数字,最后一个数字,中间数字都是1。

第一种情况下,中间数字位于后面的子数组(绿色),第二种情况,中间数字位于前面的子数组(紫色)。

因此当两个指针指向的数字和中间数字相同的时候,我们无法确定中间数字1是属于前面的子数组(紫色)还是属于后面的子数组(绿色)。

也就无法移动指针来缩小查找的范围。这时只能使用顺序查找法查找。

3、代码

3.1 Java代码

import java.util.ArrayList;
public class Solution {public int minNumberInRotateArray(int [] array) {int size = array.length;if(size==0)return 0;int l_index=0;int r_index=size-1;int m_index=-1;while(array[l_index]>=array[r_index]){if(r_index - l_index==1)break;//当只有两个数时,肯定是第二个数是最小数m_index=l_index+(r_index-l_index)/2;/* 如果左中右都相等,例如101111,则无法判断,只能按顺序查找 */if(array[l_index]==array[m_index] && array[m_index]==array[r_index])return MinInorder(array,l_index,r_index);if(array[m_index]>=array[l_index])l_index=m_index;else r_index=m_index;}return array[r_index];}/* 按顺序查找 */int MinInorder(int [] array ,int l,int r){int min=array[l];for(int i=l;i<=r;++i){if(array[i]<min)min=array[i];}return min;}
}

3.2、C++代码

class Solution {public:int minNumberInRotateArray(vector<int> rotateArray) {int size = rotateArray.size();if(size == 0)return 0;int l_index = 0;int r_index = size - 1;int m_index = -1;while(rotateArray[l_index]>=rotateArray[r_index]){if(r_index - l_index == 1)break;m_index = l_index + (r_index-l_index)/2;/* 当左中右都相等时,例如101111,无法判断,只能顺序查找 */if(rotateArray[l_index]==rotateArray[m_index] && rotateArray[m_index]==rotateArray[r_index])return MinInorder(rotateArray,l_index,r_index);if(rotateArray[m_index]>=rotateArray[l_index])l_index = m_index;else if(rotateArray[m_index]<=rotateArray[r_index])r_index = m_index;}return rotateArray[r_index];}int MinInorder(vector<int> rotateArray, int index1, int index2){int Min = rotateArray[index1];for (int i = index1 + 1; i < index2; i++){if (rotateArray[i] < Min){Min = rotateArray[i];}}return Min;}
};

4、总结

注意二分查找的应用与特殊情况的考虑

探讨学习加:
qq:1126137994
微信:liu1126137994

【剑指offer - C++/Java】6、旋转数组的最小数字相关推荐

  1. 剑指offer面试题[8]-旋转数组的最小数字

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

  2. 剑指offer(12)旋转数组的最小数字

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

  3. 剑指Offer - 面试题11. 旋转数组的最小数字(二分查找)

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

  4. 剑指offer面试题11. 旋转数组的最小数字(二分查找)

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

  5. 剑指offe面试题8 旋转数组的最小数字 (java实现)

    解题思路: 针对旋转数组的特点,即旋转后,数组的前半部分是有序的,后半部分是有序的. 1.先考虑一般情况:可以参考二分查找的思想,在数组中设置两个指针,一个指向数组的起始位置,一个指向数组的结束位置. ...

  6. 【剑指offer-Java版】08旋转数组的最小数字

    旋转数组最小数字:暴力方法就是遍历-有效的方法是二分,但是存在失效的情况 几个特别的测试用例需要注意下: 数组中含有多个相同的数字 最小数字就是第一个 public class _Q08 {publi ...

  7. 【LeetCode】剑指 Offer 53 - I. 在排序数组中查找数字 I

    [LeetCode]剑指 Offer 53 - I. 在排序数组中查找数字 I 文章目录 [LeetCode]剑指 Offer 53 - I. 在排序数组中查找数字 I 一.二分法 总结 一.二分法 ...

  8. 剑指offer java -查找旋转数组的最小数字

    /** * Created by wqc on 2017/7/18. * 查找旋转数组的最小数字 * 把一个数组最开始的若干个元素搬到数组的末尾,称为数组的旋转 * 输入一个递增排序的数组的一个旋转, ...

  9. j剑指offer面试题[33]-把数组排成最小的数

    题目描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 思路: 可以 ...

  10. 剑指Offer:面试题33——把数组排成最小的数(java实现)(未完待续)

    问题描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 思路1: ...

最新文章

  1. javaScript 验证码代码
  2. CAN 多于8字节的拆包组包协议
  3. 96. (GO)不同的二叉搜索树
  4. HarmonyOS之系统设置项的查询和使用
  5. python3 pygame的发射子弹自编程序
  6. python ssh
  7. 一招搞定css页面布局
  8. python时间格式化
  9. 用VS2008做博客¥(^_^)¥
  10. 解决:安装R包时,经常提示“package ‘readr’ is not available (for R version 3.5.1)”的问题
  11. 计算机上机单招试题及答案,全国高职单招计算机类模拟试卷考卷及答案
  12. java day11【final、权限、内部类、引用类型】
  13. Sina weibo新浪微博 API返回信息详解
  14. 过麦--回忆里面的山东
  15. 顺丰,四通一达,京东,百世,天天,德邦快递接口java-demo【快递100API】
  16. Android攻城狮数据存储之SharedPreferences
  17. adb命令重置_ADB命令手册大全
  18. pandas把一个excel的特定数据写到另一个excel_Python读写Excel文件第三方库汇总,你想要的都在这儿!...
  19. 如何通过Apple ID找回弄丢的设备
  20. HTML5期末大作业:宠物主题网站设计——酷酷动物主题响应式网页(5页) HTML+CSS+JavaScript...

热门文章

  1. 70 include指令
  2. python中[-1]、[-1]、[-1]、[n-1]使用方法
  3. java 反射 框架_Java 反射,开发框架必备技能
  4. 假设以邻接矩阵作为图的存储结构_图的存储
  5. 22.敏捷估计与规划——Why Agile Planning Works笔记
  6. 【刷题】洛谷 P2709 小B的询问
  7. GPU版的tensorflow在windows上的安装时的错误解决方案
  8. [转]Xcode的重构功能
  9. hdu 3652 B-number 数位dp
  10. 二叉树学习笔记--先序遍历