Learnitweb

Problem 154: Find Minimum in Rotated Sorted Array II

This is a follow-up to LeetCode 153, but with one important difference:

The rotated sorted array may contain duplicates.

Example:

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

Because duplicates exist, the classic binary-search logic from problem 153 does not work directly and needs modification.


Understanding the Problem

The array is:

Sorted
Rotated at some pivot
Contains duplicates

Goal: return the minimum element.

Example:

Original sorted array: [0, 1, 2, 2, 2]
Possible rotation: [2, 2, 2, 0, 1]

Minimum is still 0.

The challenge is that duplicates can hide the pivot, breaking simple comparisons.


Why Duplicates Make It Hard

In problem 153 (no duplicates), comparing:

nums[mid] vs nums[right]

tells exactly which side is sorted and where the pivot lies.

But with duplicates:

nums[mid] = nums[right]

does not give any information.
Both halves could still be valid.

So we need a special rule to handle duplicates.


Approach (Explained in Simple Language)

We still use binary search, but with one extra rule.

1. Use two pointers

left = 0
right = n−1

2. Compute mid each step

mid = left + (right − left) / 2

3. Comparison logic

Case 1: nums[mid] < nums[right]
Minimum is in the left half including mid.
right = mid

Case 2: nums[mid] > nums[right]
Minimum is in the right half.
left = mid + 1

Case 3: nums[mid] == nums[right]
Duplicates → we cannot decide the direction.
So simply reduce search space:
right–

This is the only difference from problem 153.

4. When left == right

Minimum is nums[left].

This algorithm ensures worst-case O(n) (when many duplicates exist), but average is still O(log n).


Java Code

public class FindMinimumInRotatedSortedArrayII {

    public int findMin(int[] nums) {

        int left = 0;
        int right = nums.length - 1;

        while (left < right) {

            int mid = left + (right - left) / 2;

            if (nums[mid] < nums[right]) {

                right = mid;

            } else if (nums[mid] > nums[right]) {

                left = mid + 1;

            } else {

                right--;
            }
        }

        return nums[left];
    }

    public static void main(String[] args) {
        FindMinimumInRotatedSortedArrayII solution = new FindMinimumInRotatedSortedArrayII();
        int[] nums = {2,2,2,0,1};
        System.out.println(solution.findMin(nums));
    }
}

Dry Run

Input:
nums = [2, 2, 2, 0, 1]

left = 0
right = 4


Step 1

left = 0, right = 4
mid = 2
nums[mid] = 2
nums[right] = 1

2 > 1 → minimum is in right half

left = mid + 1 = 3


Step 2

left = 3, right = 4
mid = (3+4)/2 = 3

nums[mid] = 0
nums[right] = 1

0 < 1 → minimum is in left half including mid

right = mid = 3


Step 3

left = 3, right = 3
Exit loop.

Return nums[left] = 0

Minimum = 0


Why This Approach Works

Duplicates hide the pivot, so comparing mid and right becomes ambiguous when equal.

The rule right– safely reduces the search space without losing the minimum.

This guarantees correctness because:

If nums[mid] == nums[right],
We know nums[right] cannot be the unique minimum (since there are duplicates),
But nums[right] might still be equal to the minimum, so shrinking the search space preserves correctness.

Average complexity: O(log n)
Worst-case (all elements equal): O(n)