Solution to Find Minimum in Rotated Sorted Array.

Approach 1

Intuition : Minimum element is the first element in the array that is less than or equal to the last element in the array. Now the problem becomes a simple binary search to identify the first element that satisfy this criteria.

class Solution {
    public int findMin(int[] nums) {
        int l = 0;
        int r = nums.length - 1;
        int indexOfLastElement = nums.length - 1;
        int boundaryIndex = -1;
        while (l <= r) {
            int m = l + (r - l)/2;
            if (nums[m] <= nums[indexOfLastElement]) {
                boundaryIndex = m;
                r = m - 1;
            } else {
                l = m + 1;
            }
        }

        return nums[boundaryIndex];
    }
}

Approach 2

In this approach you apply two rules during the search process.

Rule 1: If mid element is less than element at mid-1, that means mid element is the pivot element. If you think about it, the array being sorted and rotated, the pivot element is the only place a transition happens from high to low.

Rule 2: If mid element is greater than the last element in the array, then we need to search for smallest element in the second half.

While going through the code, have a look at the diagram in this link to get a grasp on how we are picking the right partition during each iteration.

class Solution {
    public int findMin(int[] nums) {
        int low=0, high=nums.length-1;
        
        if (nums.length == 1)
            return nums[0];
        
        if (nums.length == 2)
            return nums[0] < nums[1] ? nums[0] : nums[1];
        
        // handle [1,2,3,4,5] kind of inputs
        if (nums[low] < nums[high])
            return nums[low];

        while(low<=high) {
            int mid = low + (high - low)/2;
            // if current element is less than previous element
            // that means, current element is the pivot-element/min.
            if (nums[mid] < nums[mid-1]) {
              return nums[mid];
            } else if (nums[mid] > nums[high]) {
                // if current mid element is greater than last element
                // we need to search for smallest element in the second half.
                // Use the diagram in this link to understand why its so -
                // http://theoryofprogramming.com/2017/12/16/find-pivot-element-sorted-rotated-array/ 
                low = mid + 1;
            } 
            else {
                high = mid;
            }
        }

        return -1;
    }
}

Approach 3

The code for approach 3 is very simple and does not require additional checks for edge case handling. This solution was given by @JJH11 in the leetcode discussion thread.

Two key rules to help understand the solution.

Rule 1: When you sort and rotate an array, you create two parts of the array, one part will be sorted and another part will be unsorted. You can determine whether a part is sorted by comparing the first and last element of that part. For ex: if nums[low] > nums[mid], that means elements from low to mid are not sorted.

Rule 2: The min element will be in the unsorted part of the sorted and rotated array.

    public int findMin(int[] nums) {
        int low = 0, high = nums.length-1;
        while(low < high){
            int mid = (low + high) / 2;
            //check if the first half is unsorted
            if(nums[low] > nums[mid]) {
                high = mid;
            //check if the second half is unsorted
            }else if(nums[mid] > nums[high]) {
                low = mid + 1;
            }else {
                //return the first item in the remaining list
                // since now both half of the items are sorted. 
                return nums[low];
            }
        }
        
        return nums[low];
    }