Easy | LeetCode 154 | 剑指 Offer 11. 旋转数组的最小数字 | 二分法

剑指 Offer 11. 旋转数组的最小数字

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

示例 1:

输入:[3,4,5,1,2]
输出:1

示例 2:

输入:[2,2,2,0,1]
输出:0

解题思路

二分法: 对于一个递增有序(不是严格递增, 可能有重复)的数组的旋转, 旋转之后的特点可能如下:分为两部分递增有序, 并且最后一个数, 小于等于第一个数(实际发生了旋转之后)。

所以二分的策略如下, 每次把中间值mid和最右边元素比, 如果大于最右边元素, 则此mid一定落在左半边的递增数组, 此时, 应当排除掉[left, mid], 新区间为[mid+1, right]。如果mid值小于最右边元素, 则此mid一定落在右半边, 此时应当排除掉区间(mid, right], 新区间为[left, mid]; 当前值等于最右边值, 此时没法确定当前的mid值落在最左边还是最右边, 但是也不能什么都不做(不改变区间大小的话, 就会死循环), 所以这时, 可以让右指针向左移一位, 不会对结果产生影响。

public int minArray(int[] numbers) {
    int left = 0, right = numbers.length - 1;
    int mid = 0;
    while (left < right) {
        mid = (left + right) >> 1;
        if (numbers[mid] > numbers[right]) {
            left = mid + 1;
        } else if (numbers[mid] < numbers[right]) {
            right = mid;
        } else {
            right--;
        }
    }
    return numbers[left];
}
原文地址:https://www.cnblogs.com/chenrj97/p/14321055.html