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

    示例 1:

    1. 输入:nums = [3,4,5,1,2]
    2. 输出:1
    3. 解释:原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。

    示例 2:

    1. 输入:nums = [4,5,6,7,0,1,2]
    2. 输出:0
    3. 解释:原数组为 [0,1,2,4,5,6,7] ,旋转 4 次得到输入数组。

    示例 3:

    1. 输入:nums = [11,13,15,17]
    2. 输出:11
    3. 解释:原数组为 [11,13,15,17] ,旋转 4 次得到输入数组。

    题解1:二分查找
    其实跟昨天的题基本是一样的,昨天在求解时找出了最大值,现在是求最小值。自己写的时候还是出现了一点问题,在数组全部是升序时无法求出最小值。所以加了一个判定,在这种情况下直接返回最左侧元素。

    1. class Solution {
    2. public int findMin(int[] nums) {
    3. int n=nums.length,l=0,r=n-1,mid;
    4. if(nums[l]<nums[r])
    5. return nums[l];
    6. while(l<r-1){
    7. mid = (l+r)/2;
    8. if(nums[l]>nums[mid])
    9. r=mid;
    10. else
    11. l=mid;
    12. }
    13. return nums[r];
    14. }
    15. }

    官方题解跟我的方法有两点不同。第一点,判定方法可以满足数组为升序时仍然可以找出最小值;第二点,在应当向右边搜索时,左指针可以向右移动一位,因为左指针指向的元素不可能为最小值。

    1. class Solution {
    2. public int findMin(int[] nums) {
    3. int low = 0;
    4. int high = nums.length - 1;
    5. while (low < high) {
    6. int pivot = low + (high - low) / 2;
    7. if (nums[pivot] < nums[high]) {
    8. high = pivot;
    9. } else {
    10. low = pivot + 1;
    11. }
    12. }
    13. return nums[low];
    14. }
    15. }