The First True pattern on a non-obvious condition. The secret: compare every element to the last element to reveal the hidden boolean structure.
Suppose an array of length n sorted in ascending order is rotated between 1 and n times. Given the rotated array nums of unique elements, return the minimum element. You must write an algorithm that runs in O(log n) time.
A rotated sorted array looks chaotic at first glance. But it has a clean structure: it consists of exactly two sorted segments joined together. The minimum is always the first element of the second (smaller) segment — the exact point where the rotation happened.
The trick is finding a condition that separates these two segments. Comparing each element to the last element works perfectly:
Array: [4, 5, 6, 7, 0, 1, 2]
7 <= 2? No → condition FALSE. The minimum is in the right half. left = 4.
1 <= 2? Yes → condition TRUE. Save boundary=5, search left: right = 4.
0 <= 2? Yes → condition TRUE. Save boundary=4, search left: right = 3.
Return nums[boundary] = nums[4] = 0. Correct!
Why compare with last and not first? The last element is always in the lower sorted segment. So anything <= last is also in the lower segment. If you compared with the first element, you'd be comparing against the upper segment which doesn't give a clean boundary.
class Solution { public int findMin(int[] nums) { int left = 0; int right = nums.length - 1; int boundary = 0; int last = nums[nums.length - 1]; while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] <= last) { // In lower sorted segment — could be the minimum boundary = mid; right = mid - 1; // search left for an earlier entry } else { // In upper sorted segment — minimum is to the right left = mid + 1; } } return nums[boundary]; } }
class Solution: def findMin(self, nums: list[int]) -> int: left, right = 0, len(nums) - 1 boundary = 0 last = nums[-1] while left <= right: mid = left + (right - left) // 2 if nums[mid] <= last: # In lower sorted segment — could be the minimum boundary = mid right = mid - 1 # search left for an earlier entry else: # In upper sorted segment — minimum is to the right left = mid + 1 return nums[boundary]
Connection to LC 154: The next problem (LC 154) adds duplicate elements to this exact scenario. The core logic is identical — but you need an extra step to handle ties in the comparison. See the LC 154 page for the modification.