🧠
Binary Search (Recursive)
💡 This approach uses recursion to implement binary search, which some find more intuitive. It also achieves O(log n) time but uses extra stack space.
Intuition
Recursively divide the array into halves, checking the middle element and searching the appropriate half until the insertion point is found.
Algorithm
- Define a recursive function with left and right pointers.
- If left > right, return left as insertion position.
- Calculate mid index.
- If nums[mid] equals target, return mid.
- If nums[mid] < target, recurse on right half (mid+1 to right).
- Else recurse on left half (left to mid-1).
💡 The base case returns the insertion point when search space is empty.
def searchInsert(nums, target):
def binary_search(left, right):
if left > right:
return left
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
return binary_search(mid + 1, right)
else:
return binary_search(left, mid - 1)
return binary_search(0, len(nums) - 1)
# Driver code
if __name__ == '__main__':
print(searchInsert([1,3,5,6], 5)) # 2
print(searchInsert([1,3,5,6], 2)) # 1
print(searchInsert([1,3,5,6], 7)) # 4
print(searchInsert([1,3,5,6], 0)) # 0
Line Notes
def binary_search(left, right):Helper function to perform recursive binary search
if left > right:Base case: search space empty, return insertion point
mid = (left + right) // 2Calculate middle index
if nums[mid] == target:Return mid if target found
elif nums[mid] < target:Recurse on right half if target greater
else:Recurse on left half if target smaller
public class Solution {
public static int searchInsert(int[] nums, int target) {
return binarySearch(nums, target, 0, nums.length - 1);
}
private static int binarySearch(int[] nums, int target, int left, int right) {
if (left > right) {
return left;
}
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
return binarySearch(nums, target, mid + 1, right);
} else {
return binarySearch(nums, target, left, mid - 1);
}
}
public static void main(String[] args) {
System.out.println(searchInsert(new int[]{1,3,5,6}, 5)); // 2
System.out.println(searchInsert(new int[]{1,3,5,6}, 2)); // 1
System.out.println(searchInsert(new int[]{1,3,5,6}, 7)); // 4
System.out.println(searchInsert(new int[]{1,3,5,6}, 0)); // 0
}
}
Line Notes
return binarySearch(nums, target, 0, nums.length - 1);Start recursive search on full array
if (left > right)Base case: empty search space, return insertion point
int mid = left + (right - left) / 2;Calculate middle index safely
if (nums[mid] == target)Return mid if target found
else if (nums[mid] < target)Recurse on right half if target greater
elseRecurse on left half if target smaller
#include <iostream>
#include <vector>
using namespace std;
int binarySearch(vector<int>& nums, int target, int left, int right) {
if (left > right) {
return left;
}
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
return binarySearch(nums, target, mid + 1, right);
} else {
return binarySearch(nums, target, left, mid - 1);
}
}
int searchInsert(vector<int>& nums, int target) {
return binarySearch(nums, target, 0, nums.size() - 1);
}
int main() {
vector<int> nums1 = {1,3,5,6};
cout << searchInsert(nums1, 5) << endl; // 2
cout << searchInsert(nums1, 2) << endl; // 1
cout << searchInsert(nums1, 7) << endl; // 4
cout << searchInsert(nums1, 0) << endl; // 0
return 0;
}
Line Notes
if (left > right)Base case: no elements left, return insertion point
int mid = left + (right - left) / 2;Calculate middle index safely
if (nums[mid] == target)Return mid if target found
else if (nums[mid] < target)Recurse on right half if target greater
elseRecurse on left half if target smaller
return binarySearch(nums, target, 0, nums.size() - 1);Start recursive search
function searchInsert(nums, target) {
function binarySearch(left, right) {
if (left > right) {
return left;
}
let mid = Math.floor((left + right) / 2);
if (nums[mid] === target) {
return mid;
} else if (nums[mid] < target) {
return binarySearch(mid + 1, right);
} else {
return binarySearch(left, mid - 1);
}
}
return binarySearch(0, nums.length - 1);
}
// Test cases
console.log(searchInsert([1,3,5,6], 5)); // 2
console.log(searchInsert([1,3,5,6], 2)); // 1
console.log(searchInsert([1,3,5,6], 7)); // 4
console.log(searchInsert([1,3,5,6], 0)); // 0
Line Notes
function binarySearch(left, right)Recursive helper function for binary search
if (left > right)Base case: empty search space, return insertion point
let mid = Math.floor((left + right) / 2);Calculate middle index
if (nums[mid] === target)Return mid if target found
else if (nums[mid] < target)Recurse on right half if target greater
elseRecurse on left half if target smaller
TimeO(log n)
SpaceO(log n)
Recursive calls halve the search space each time, but recursion adds stack space proportional to log n.
💡 For n=100, about 7 recursive calls are made, using extra memory compared to iterative.
Interview Verdict: Accepted, but uses extra stack space
Recursive binary search is elegant but less space efficient than iterative.