LeetCode – Find Minimum in Rotated Sorted Array (Java)

Suppose a sorted array 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.You may assume no duplicate exists in the array.

Analysis

This problem is a binary search and the key is breaking the array to two parts, so that we only need to work on half of the array each time.

If we pick the middle element, we can compare the middle element with the leftmost (or rightmost) element. If the middle element is less than leftmost, the left half should be selected; if the middle element is greater than the leftmost (or rightmost), the right half should be selected. Using recursion or iteration, this problem can be solved in time log(n).

In addition, in any rotated sorted array, the rightmost element should be less than the left-most element, otherwise, the sorted array is not rotated and we can simply pick the leftmost element as the minimum.

Java Solution 1 - Recursion

Define a helper function, otherwise, we will need to use Arrays.copyOfRange() function, which may be expensive for large arrays.

public int findMin(int[] num) {
	return findMin(num, 0, num.length - 1);
}
 
public int findMin(int[] num, int left, int right) {
	if (left == right)
		return num[left];
	if ((right - left) == 1)
		return Math.min(num[left], num[right]);
 
	int middle = left + (right - left) / 2;
 
	// not rotated
	if (num[left] < num[right]) {
		return num[left];
 
	// go right side
	} else if (num[middle] > num[left]) {
		return findMin(num, middle, right);
 
	// go left side
	} else {
		return findMin(num, left, middle);
	}
}

Java Solution 2 - Iteration

public int findMin(int[] nums) {
    if(nums==null || nums.length==0)
        return -1;
 
    if(nums.length==1)
        return nums[0];
 
    int left=0;
    int right=nums.length-1;
 
    //not rotated
    if(nums[left]<nums[right])
        return nums[left];
 
    while(left <= right){
        if(right-left==1){
            return nums[right];
        }
 
        int m = left + (right-left)/2;
 
        if(nums[m] > nums[right])
            left = m;
        else
            right = m;
    }
 
    return nums[left];
}

Or

/*
To understand the boundaries, use the following 3 examples:
[2,1], [2,3,1], [3,1,2]
*/
public int findMin(int[] nums) {
    if(nums==null || nums.length==0)
        return -1;
 
    int i=0; 
    int j=nums.length-1;
 
    while(i<=j){
        if(nums[i]<=nums[j])
            return nums[i];
 
        int m=(i+j)/2;
 
        if(nums[m]>=nums[i]){
            i=m+1;
        }else{
            j=m;
        }
    }
 
    return -1;
}
Category >> Algorithms  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>

  1. Burhan COKCA on 2015-5-16

    Simpler solution with O(n) time complexity in worst case.

    public int findMin(int[] nums) {

    if(nums.length == 1) return nums[0];

    for(int i =0; i nums[i+1])

    return nums[i+1];

    }

    return nums[0];

    }

  2. Mr. Lazy on 2015-5-31

    The problem is itself about using binary search .. Why use O(n) solution? that a very obvious solution 😛

  3. karthik varma on 2015-6-10

    The above proposed algorithm works in O(logn), since the problem statement says no duplicates.

  4. Larry Okeke on 2016-3-24


    public static void solution(){

    arr = new int[] {6, 7, 8, 9, 1, 2, 3, 4, 5};

    int solut = recurse(0, 4, 8);

    }

    public static int recurse(int l, int middle, int r){

    log("l: " + arr[l] + " r: "+ arr[r]);

    if(r - l <= 2) return (arr[l] < arr[r]) ? arr[l] : arr[r];

    if(arr[l] arr[l])

    return recurse(l, (middle/2)+1, middle);

    return recurse(middle, middle + middle/2, r) ;

    }

  5. Shariq Aziz on 2016-6-11

    No it takes O(n) time even without dups

  6. TechSawi on 2017-2-22

    Solution doens’t work for {5, 6, 7, 4, 0, 1, 2}. I rotated {0, 1, 2, 4, 5, 6, 7} in the middle and then try to find the minimum. It is showing ‘4’ instead of ‘0’

  7. Snow on 2017-3-6

    Because you rotated it wrong. The pivot is not a stationary number in this question. SO you don’t keep 4 locked.

Leave a comment

*