Question

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).

Find the minimum element.

The array may contain duplicates.

Example 1:

Input: [1,3,5]
Output: 1

Example 2:

Input: [2,2,2,0,1]
Output: 0

Thinking:

  • Method: 遍历
class Solution {
    public int findMin(int[] nums) {
        int pre = nums[0];
        for(int i = 1; i < nums.length; i++){
            if(nums[i] < pre)
                return nums[i];
        }
        return nums[0];
    }
}
  • Method 2: 二分法
class Solution {
    public int findMin(int[] nums) {
        int high = nums.length - 1;
        int low = 0;
        return findMin(nums, low, high);
    }
    private int findMin(int[] nums, int low, int high){
        int mid = (low + high) / 2;
        if(low + 1 >= high) return Math.min(nums[low], nums[high]);
        if(nums[mid] == nums[high])		//移除尾部的重复
            return findMin(nums, low, high-1);
        else if(nums[mid] >= nums[low] && nums[mid] > nums[high])
            return findMin(nums, mid, high);	//最小值在右半部
        else
            return findMin(nums, low, mid);	//在前半部
    }
}

二刷

和上一题不同的是,这道题需要通过判断等号然后去重。

class Solution {
    public int findMin(int[] nums) {
        int high = nums.length - 1;
        int low = 0;
        return find(nums, low, high);
    }
    private int find(int[] nums, int low, int high){
        int mid = low + (high - low) / 2;
        if(low == high) return nums[low];
        if(nums[mid] == nums[high])
            return find(nums, low, high - 1);
        else if(nums[mid] >= nums[low] && nums[high] < nums[mid])
            return find(nums, mid + 1, high);
        else
            return find(nums, low, mid);
    }
}

三刷

class Solution {
    public int findMin(int[] nums) {
        if(nums.length == 1) return nums[0];
        int low = 0, high = nums.length - 1;
        return find(nums, low, high);
    }
    private int find(int[] nums, int low, int high){
        if(low >= high) return nums[low];
        int mid = low + (high - low) / 2;
        if(nums[mid] == nums[high])
            return find(nums, low, high - 1);
        else if(nums[mid] >= nums[low]) //左侧是顺序的
            return Math.min(nums[low], find(nums, mid + 1, high));
        else
            return Math.min(nums[mid], find(nums, low + 1, mid - 1));
    }
}