Topics
Idea
This problem is similar to min element in a rotated sorted array, but nums
contain duplicates. This means that we can’t apply the binary search boolean array framework like before. For cases: [4, 1, 3, 3, 3]
, [4, 5, 3, 3, 3]
, the middle element is equal to both the last element, so we can’t decide which half to “choose” by comparing nums[mid]
with any of the endpoints. Thus, for such a case, best we can do is skip the last element and shrink search space by just one element.
Thus, we must add extra logic to handle ambiguous cases:
- When
nums[mid] < nums[hi]
:
This guarantees that the minimum is atmid
or to its left, so update your candidate answer and movehi
tomid
- When
nums[mid] > nums[hi]
:
The minimum must lie to the right ofmid
, so setlo
tomid + 1
- When
nums[mid] == nums[hi]
:
This is the ambiguous case. Here, you can’t tell which side contains the minimum, so you shrink the search space by decrementinghi
Warning
Note that the logic here is to compare
nums[mid]
withnums[hi]
and not withnums[n-1]
.
Code
Relies on the vanilla binary search implementation
class Solution {
public:
int findMin(vector<int>& nums) {
int lo = 0, hi = nums.size() - 1;
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (nums[mid] < nums[hi]) {
hi = mid;
} else if (nums[mid] > nums[hi]) {
lo = mid + 1;
} else {
// nums[mid] == nums[hi]: we cannot decide, shrink the search space.
hi--;
}
}
return nums[lo];
}
};