剑指offer--旋转数组的最小数字

原创 2017年04月15日 20:58:40

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


分析:
这道题最直观的解法并不难。从头到尾遍历数组一次,就能找出最小的元素,时间复杂度显然是O(N)。但这个思路没有利用输入数组的特性,我们应该能找到更好的解法。
我们注意到旋转之后的数组实际上可以划分为两个排序的子数组,而且前面的子数组的元素都大于或者等于后面子数组的元素。我们还可以注意到最小的元素刚好是这两个子数组的分界线。我们试着用二元查找法的思路在寻找这个最小的元素。
首先我们用两个指针,分别指向数组的第一个元素和最后一个元素。按照题目旋转的规则,第一个元素应该是大于或者等于最后一个元素的(这其实不完全对,还有特例。后面再讨论特例)。
接着我们得到处在数组中间的元素。如果该中间元素位于前面的递增子数组,那么它应该大于或者等于第一个指针指向的元素。此时数组中最小的元素应该位于该中间元素的后面。我们可以把第一指针指向该中间元素,这样可以缩小寻找的范围。同样,如果中间元素位于后面的递增子数组,那么它应该小于或者等于第二个指针指向的元素。此时该数组中最小的元素应该位于该中间元素的前面。我们可以把第二个指针指向该中间元素,这样同样可以缩小寻找的范围。我们接着再用更新之后的两个指针,去得到和比较新的中间元素,循环下去。
按照上述的思路,我们的第一个指针总是指向前面递增数组的元素,而第二个指针总是指向后面递增数组的元素。最后第一个指针将指向前面子数组的最后一个元素,而第二个指针会指向后面子数组的第一个元素。也就是它们最终会指向两个相邻的元素,而第二个指针指向的刚好是最小的元素。这就是循环结束的条件。


代码如下:

public class Solution {

    public int minNumberInRotateArray(int [] array) {
        if ( array == null || array.length < 1){
            return -1;
        }
        int len = array.length;
        int low = 0;
        int high = len - 1;
        int mid = (low + high) / 2;

        //如果首个元素小于最后一个元素,表明数组是排序的。 
        if (array[low] < array[high]){
            return array[low];
        }

        //当low指针与high指针相邻的时候,high指针指向的就是最小元素  
        if ( high - low == 1){
            return array[high];
        }

        while(low < high){
            mid = ( low + high) / 2;
            if(mid==low){//if there are only two elements left  
                return (array[low] < array[high])? array[low] : array[high];  
            }  
            if ( array[mid] >= array[low]){  
                low = mid;
            }else if ( array[mid] <= array[high]){
                high = mid;
            }
        }
        return array[mid];
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载。若需转载,请注明http://blog.csdn.net/qq_30091945 举报

相关文章推荐

剑指offer 面试题8—旋转数组的最小数字

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

剑指offer--面试题8: 旋转数组的最小数字

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

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

【剑指offer】旋转数组的最小数字&&二分查找

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

剑指Offer——面试题8:旋转数组的最小数字

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

剑指offer 旋转数组的最小数字

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

剑指Offer--008-旋转数组的最小数字

链接 牛客OJ:旋转数组的最小数字 九度OJ:http://ac.jobdu.com/problem.php?pid=1386 GitHub代码: 008-旋转数组的最小数字...

剑指Offer面试题8[旋转数组的最小数字]

剑指Offer面试题8[旋转数组的最小数字]

剑指offer OJ,旋转数组的最小数字

时间限制:1秒空间限制:32768K 通过比例:15.05% 最佳记录:0 ms|8552K (来自 牛客841129号) 题目描述把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的...

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

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

剑指offer--旋转数组的最小数字

记录来自《剑指offer》上的算法题。题目描述如下: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个选择,输出旋转数组的最小元素。例如数组{3,4,...
  • lc013
  • lc013
  • 2016-12-20 10:44
  • 136
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)