剑指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(6)-旋转数组的最小数字

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

【剑指Offer面试编程题】题目1386:旋转数组的最小数字--九度OJ

本题可以采用投机取巧的方法来完成,由于所有输入数据都必须要读入,题目的旋转数组的最小元素即可以看做从所有输入元素中寻找最小元素。这样的话,我们可以再输入元素的同时确定最小元素,如果当前输入元素比目标元...

《剑指Offer》查找和排序——旋转数组中的最小数字

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

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

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

剑指offer(C++)——旋转数组的最小数字

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

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

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

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

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

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

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

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

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

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

/* 旋转数组的最小数字: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转, 输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:剑指offer--旋转数组的最小数字
举报原因:
原因补充:

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