描述

旋转数组(非递减)的最小数

把一个数组最开始的若干位搬到数组的末尾,称为旋转数组。

例子

Input:
	
Output:
	

思路

采用二分的方式来处理,

正常情况

4 5 6 7 1 2,分成两部分4 5 6,7 1 2;可知4 5 6为非递减数列,7 1 2为旋转数组,故结果在循环数组中,可以去掉另外一半数组;

两种特殊情况:

(1)1 1 1 1 0 1,num[left] == num[mid] == num[right],此时无法分区,故只能遍历

(2)4 5 6 1 2 3,分区后两个部分均为非递减数组,则返回num[left]和num[mid+1]中较小的数即可。

代码

public class Demo011 {
    public static void main(String[] args) {
        int [] arr = new int[] {1,1,1,0,1};
        System.out.println(searchMin(arr,arr.length));
    }

    public static int searchMin(int [] array, int length) {
        int left = 0, right = length - 1;
        int mid = (left + right) / 2;
        while(left < right) {
            // 分区间后刚好左右都为非递减数组
            if(array[left] < array[mid] && array[mid+1] < array[right]) {
                if (array[left] > array[mid+1]) {
                    left = mid+1;
                }
                break;
            }
            // 无法分区间情况
            if (array[left] == array[mid] && array[mid] == array[right]) {
                int minIndex = left;
                for (int i = left; i <= right; i++) {
                    if (array[minIndex] > array[i]) {
                        minIndex = i;
                    }
                }
                left = minIndex;
                break;
            }
            // 正常分区间
            if (array[left] < array[mid]) {
                // 左侧为非递减数组,右侧为旋转数组==>取右侧
                left = mid+1;
            } else {
                // 取左侧
                right = mid - 1;
            }
        }
        return array[left];
    }
}