🧠
Binary Search with Additional Checks (Explicit Pivot Detection)
💡 This approach explicitly checks if mid is the pivot (minimum) by comparing with neighbors, adding clarity at the cost of slightly more code.
Intuition
The minimum element is the only element smaller than its previous element. By checking mid against neighbors, we can identify the pivot directly.
Algorithm
- Initialize left and right pointers.
- While left <= right, find mid.
- Check if mid element is smaller than previous element; if yes, return mid element.
- Check if mid element is greater than next element; if yes, return next element.
- If mid element is greater than left element, move left to mid + 1.
- Else, move right to mid - 1.
- Return first element if no pivot found.
💡 This approach is more explicit but requires careful boundary checks to avoid index errors.
def find_min(nums):
left, right = 0, len(nums) - 1
n = len(nums)
while left <= right:
mid = (left + right) // 2
prev = (mid - 1 + n) % n
next_ = (mid + 1) % n
if nums[mid] < nums[prev]:
return nums[mid]
if nums[mid] > nums[next_]:
return nums[next_]
if nums[mid] >= nums[left]:
left = mid + 1
else:
right = mid - 1
return nums[0]
# Driver code
if __name__ == '__main__':
arr = [4,5,6,7,0,1,2]
print(find_min(arr)) # Output: 0
Line Notes
left, right = 0, len(nums) - 1Initialize search boundaries
while left <= rightLoop until pointers cross
prev = (mid - 1 + n) % nCalculate previous index circularly to avoid out-of-bounds
next_ = (mid + 1) % nCalculate next index circularly
if nums[mid] < nums[prev]Check if mid is pivot by comparing with previous
if nums[mid] > nums[next_]Check if next element is pivot
if nums[mid] >= nums[left]Decide which half to search based on mid and left
left = mid + 1Search right half if mid >= left
right = mid - 1Search left half otherwise
return nums[0]Return first element if no pivot found
public class Solution {
public static int findMin(int[] nums) {
int left = 0, right = nums.length - 1;
int n = nums.length;
while (left <= right) {
int mid = left + (right - left) / 2;
int prev = (mid - 1 + n) % n;
int next = (mid + 1) % n;
if (nums[mid] < nums[prev]) {
return nums[mid];
}
if (nums[mid] > nums[next]) {
return nums[next];
}
if (nums[mid] >= nums[left]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return nums[0];
}
public static void main(String[] args) {
int[] arr = {4,5,6,7,0,1,2};
System.out.println(findMin(arr)); // Output: 0
}
}
Line Notes
int left = 0, right = nums.length - 1Initialize pointers
while (left <= right)Loop until pointers cross
int prev = (mid - 1 + n) % nCalculate previous index circularly
int next = (mid + 1) % nCalculate next index circularly
if (nums[mid] < nums[prev])Check if mid is pivot
if (nums[mid] > nums[next])Check if next is pivot
if (nums[mid] >= nums[left])Decide which half to search
left = mid + 1Search right half
right = mid - 1Search left half
return nums[0]Return first element if no pivot found
#include <iostream>
#include <vector>
using namespace std;
int findMin(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
int n = nums.size();
while (left <= right) {
int mid = left + (right - left) / 2;
int prev = (mid - 1 + n) % n;
int next = (mid + 1) % n;
if (nums[mid] < nums[prev]) {
return nums[mid];
}
if (nums[mid] > nums[next]) {
return nums[next];
}
if (nums[mid] >= nums[left]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return nums[0];
}
int main() {
vector<int> arr = {4,5,6,7,0,1,2};
cout << findMin(arr) << endl; // Output: 0
return 0;
}
Line Notes
int left = 0, right = nums.size() - 1Initialize search boundaries
while (left <= right)Loop until pointers cross
int prev = (mid - 1 + n) % nCalculate previous index safely
int next = (mid + 1) % nCalculate next index safely
if (nums[mid] < nums[prev])Check if mid is pivot
if (nums[mid] > nums[next])Check if next is pivot
if (nums[mid] >= nums[left])Decide which half to search
left = mid + 1Search right half
right = mid - 1Search left half
return nums[0]Return first element if no pivot found
function findMin(nums) {
let left = 0, right = nums.length - 1;
const n = nums.length;
while (left <= right) {
let mid = Math.floor((left + right) / 2);
let prev = (mid - 1 + n) % n;
let next = (mid + 1) % n;
if (nums[mid] < nums[prev]) {
return nums[mid];
}
if (nums[mid] > nums[next]) {
return nums[next];
}
if (nums[mid] >= nums[left]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return nums[0];
}
// Test
console.log(findMin([4,5,6,7,0,1,2])); // Output: 0
Line Notes
let left = 0, right = nums.length - 1Initialize pointers
while (left <= right)Loop until pointers cross
let prev = (mid - 1 + n) % nCalculate previous index circularly
let next = (mid + 1) % nCalculate next index circularly
if (nums[mid] < nums[prev])Check if mid is pivot
if (nums[mid] > nums[next])Check if next is pivot
if (nums[mid] >= nums[left])Decide which half to search
left = mid + 1Search right half
right = mid - 1Search left half
return nums[0]Return first element if no pivot found
Binary search with explicit pivot checks still halves search space each iteration.
💡 This approach is slightly more complex but still efficient for large inputs.
Interview Verdict: Accepted and optimal, but more verbose
Good to know for understanding pivot properties, but usually the simpler binary search is preferred.