Water2Wine

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

题目描述:

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

题目思考:

首先最直观的是遍历数组,当遇到第一组前面比其大,后面比其小的数时,即是答案。

这种算法的时间复杂度是O(n),但显然在这种排序数组的变式中,O(logn)的时间复杂度才是最优的,这就让我们想到使用二分法来解决。
实际上,遇到排序数组找数字题,最直观最有效的就是二分法。

具体的思路如下:

  1. 因为题目中并没有给我们一些范围,所以我们可以自己设置,可以每次以数组中间为间,分别判断左右两个区间。
  2. 如果左区间或者右区间是非递增的,那么就说明最小数在这个区间内,我们可以使用while循环迭代求解,也可以递归求解
  3. 最后需要注意的点是题目中的描述是非递减,所以就有可能遇到区间的两个端点相同的情况。在这种情况下,我们只需要移动端点的一端,再进行比较即可。
public int minNumberInRotateArray(int [] array) {
        // 使用二分,判断条件是是否非递增
        // 同时如果首尾相同,则收缩
        if(array.length == 0){
            return 0;
        }
        int low = 0;
        int high = array.length - 1;
        int mid = 0;
        while(low < high){
            // 子数组是非递减的数组,10111
            if (array[low] < array[high])
                return array[low];
            mid = low + (high - low) / 2;
            if(array[mid] > array[low])
                low = mid + 1;
            else if(array[mid] < array[high])
                high = mid;
            else low++;
        }
        return array[low];
    }
posted on 2020-03-07 13:07  Water2Wine  阅读(209)  评论(0编辑  收藏  举报