🧠
Binary Search with Pivot Finding + Normal Binary Search
💡 This approach first finds the rotation pivot (smallest element) and then performs a normal binary search in the appropriate subarray. It separates concerns but requires two binary searches.
Intuition
Find the index where the rotation happened (pivot), then decide which sorted subarray to search for the target using normal binary search.
Algorithm
- Use binary search to find the pivot index where the smallest element is located.
- Determine which subarray (left or right of pivot) the target belongs to.
- Perform a standard binary search in that subarray.
- Return the index if found, else -1.
💡 This approach breaks the problem into two simpler binary searches, making it easier to reason about but slightly more complex to implement.
def find_pivot(nums):
low, high = 0, len(nums) - 1
while low < high:
mid = (low + high) // 2
if nums[mid] > nums[high]:
low = mid + 1
else:
high = mid
return low
def binary_search(nums, low, high, target):
while low <= high:
mid = (low + high) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
low = mid + 1
else:
high = mid - 1
return -1
def search(nums, target):
if not nums:
return -1
pivot = find_pivot(nums)
if nums[pivot] <= target <= nums[-1]:
return binary_search(nums, pivot, len(nums) - 1, target)
else:
return binary_search(nums, 0, pivot - 1, target)
# Driver code
if __name__ == '__main__':
print(search([4,5,6,7,0,1,2], 0)) # Output: 4
print(search([4,5,6,7,0,1,2], 3)) # Output: -1
Line Notes
while low < highLoop to find pivot by narrowing search space
if nums[mid] > nums[high]Pivot must be in right half if mid element greater than high
else: high = midPivot in left half or at mid
return lowPivot index found where smallest element is
while low <= highStandard binary search loop
if nums[mid] == targetReturn index if target found
elif nums[mid] < targetSearch right half if target greater
else: high = mid - 1Search left half otherwise
if nums[pivot] <= target <= nums[-1]Decide which subarray to search based on target range
return binary_search(...)Perform binary search in chosen subarray
public class Solution {
public static int findPivot(int[] nums) {
int low = 0, high = nums.length - 1;
while (low < high) {
int mid = low + (high - low) / 2;
if (nums[mid] > nums[high]) {
low = mid + 1;
} else {
high = mid;
}
}
return low;
}
public static int binarySearch(int[] nums, int low, int high, int target) {
while (low <= high) {
int mid = low + (high - low) / 2;
if (nums[mid] == target) return mid;
else if (nums[mid] < target) low = mid + 1;
else high = mid - 1;
}
return -1;
}
public static int search(int[] nums, int target) {
if (nums.length == 0) return -1;
int pivot = findPivot(nums);
if (target >= nums[pivot] && target <= nums[nums.length - 1]) {
return binarySearch(nums, pivot, nums.length - 1, target);
} else {
return binarySearch(nums, 0, pivot - 1, target);
}
}
public static void main(String[] args) {
System.out.println(search(new int[]{4,5,6,7,0,1,2}, 0)); // 4
System.out.println(search(new int[]{4,5,6,7,0,1,2}, 3)); // -1
}
}
Line Notes
while (low < high)Loop to find pivot by narrowing search space
if (nums[mid] > nums[high])Pivot in right half if mid > high
else high = midPivot in left half or at mid
return lowPivot index found
while (low <= high)Standard binary search loop
if (nums[mid] == target) return midReturn index if target found
else if (nums[mid] < target) low = mid + 1Search right half if target greater
else high = mid - 1Search left half otherwise
if (target >= nums[pivot] && target <= nums[nums.length - 1])Choose subarray based on target range
return binarySearch(...)Perform binary search in chosen subarray
#include <iostream>
#include <vector>
using namespace std;
int findPivot(vector<int>& nums) {
int low = 0, high = nums.size() - 1;
while (low < high) {
int mid = low + (high - low) / 2;
if (nums[mid] > nums[high]) {
low = mid + 1;
} else {
high = mid;
}
}
return low;
}
int binarySearch(vector<int>& nums, int low, int high, int target) {
while (low <= high) {
int mid = low + (high - low) / 2;
if (nums[mid] == target) return mid;
else if (nums[mid] < target) low = mid + 1;
else high = mid - 1;
}
return -1;
}
int search(vector<int>& nums, int target) {
if (nums.empty()) return -1;
int pivot = findPivot(nums);
if (target >= nums[pivot] && target <= nums.back()) {
return binarySearch(nums, pivot, nums.size() - 1, target);
} else {
return binarySearch(nums, 0, pivot - 1, target);
}
}
int main() {
vector<int> nums = {4,5,6,7,0,1,2};
cout << search(nums, 0) << endl; // 4
cout << search(nums, 3) << endl; // -1
return 0;
}
Line Notes
while (low < high)Loop to find pivot by narrowing search space
if (nums[mid] > nums[high])Pivot in right half if mid > high
else high = midPivot in left half or at mid
return lowPivot index found
while (low <= high)Standard binary search loop
if (nums[mid] == target) return midReturn index if target found
else if (nums[mid] < target) low = mid + 1Search right half if target greater
else high = mid - 1Search left half otherwise
if (target >= nums[pivot] && target <= nums.back())Choose subarray based on target range
return binarySearch(...)Perform binary search in chosen subarray
function findPivot(nums) {
let low = 0, high = nums.length - 1;
while (low < high) {
let mid = Math.floor((low + high) / 2);
if (nums[mid] > nums[high]) {
low = mid + 1;
} else {
high = mid;
}
}
return low;
}
function binarySearch(nums, low, high, target) {
while (low <= high) {
let mid = Math.floor((low + high) / 2);
if (nums[mid] === target) return mid;
else if (nums[mid] < target) low = mid + 1;
else high = mid - 1;
}
return -1;
}
function search(nums, target) {
if (nums.length === 0) return -1;
const pivot = findPivot(nums);
if (target >= nums[pivot] && target <= nums[nums.length - 1]) {
return binarySearch(nums, pivot, nums.length - 1, target);
} else {
return binarySearch(nums, 0, pivot - 1, target);
}
}
// Test cases
console.log(search([4,5,6,7,0,1,2], 0)); // 4
console.log(search([4,5,6,7,0,1,2], 3)); // -1
Line Notes
while (low < high)Loop to find pivot by narrowing search space
if (nums[mid] > nums[high])Pivot in right half if mid > high
else high = midPivot in left half or at mid
return lowPivot index found
while (low <= high)Standard binary search loop
if (nums[mid] === target) return midReturn index if target found
else if (nums[mid] < target) low = mid + 1Search right half if target greater
else high = mid - 1Search left half otherwise
if (target >= nums[pivot] && target <= nums[nums.length - 1])Choose subarray based on target range
return binarySearch(...)Perform binary search in chosen subarray
Two binary searches are performed sequentially, each O(log n), so overall time is O(log n). Space is constant.
💡 This approach is slightly more complex but still very efficient, with about twice the number of comparisons as the previous approach.
Interview Verdict: Accepted and efficient, but more complex than approach 2
This approach is useful to understand the problem structure deeply, but approach 2 is usually preferred for interviews due to simplicity.