153. 寻找旋转排序数组中的最小值

已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:
若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]
注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。
给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素

分析

题目说了,给我们的是一个元素值互不相同的数组,而且他原本是一个升序排列的数组,而我们需要返回的是数组中的最小元素。针对以上这几点,我们可以使用二分查找法。

实现
class Solution {
    public int findMin(int[] nums) {
        int left = 0;
        int right = nums.length-1;
        while(left<right){
            int mid = left + ((right-left)>>1);
            //中值 < 右值,最小值在左半边,收缩右边界
            if(nums[mid]<nums[right]) right = mid;
            else left = mid+1;
        }
        return nums[left];
    }
}
说明

以数组[4,5,6,7,0,1,2]为例
二分查找的精髓在于while循环内部的判断条件。分割数组区间的三个参数 left、mid、right。

  • 若 left<mid<right 那么说明数组没有旋转。
  • 若 left<mid>right 那么说明有旋转,最小值在右边,收缩左区间
  • 若 left>mid<right 那么说明有旋转,最小值在左边,收缩右区间
  • 若 left>mid>right 旋转无法实现,不可能出现

每个不起眼的日子,都是反败为胜的资本