🧠
Binary Search for Complement
💡 This approach uses binary search to find the complement for each element, leveraging sorted order but less efficient than two pointers.
Intuition
For each element, binary search for the number that complements it to reach the target.
Algorithm
- Iterate over each element as the first number.
- Calculate complement = target - current element.
- Binary search for complement in the subarray after current element.
- If found, return 1-based indices of current element and complement.
💡 Binary search reduces search time for complement from linear to logarithmic, improving over brute force.
def binary_search(arr, left, right, target):
while left <= right:
mid = left + (right - left) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
def two_sum_binary_search(numbers, target):
n = len(numbers)
for i in range(n):
complement = target - numbers[i]
j = binary_search(numbers, i + 1, n - 1, complement)
if j != -1:
return [i + 1, j + 1]
return []
# Driver code
if __name__ == '__main__':
print(two_sum_binary_search([2,7,11,15], 9)) # Output: [1, 2]
Line Notes
while left <= right:Standard binary search loop condition
mid = left + (right - left) // 2Calculate middle index to avoid overflow
if arr[mid] == target:Check if mid element is the complement
for i in range(n):Iterate over each element to find complement
public class TwoSumBinarySearch {
private static int binarySearch(int[] arr, int left, int right, int target) {
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) return mid;
else if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
public static int[] twoSum(int[] numbers, int target) {
int n = numbers.length;
for (int i = 0; i < n; i++) {
int complement = target - numbers[i];
int j = binarySearch(numbers, i + 1, n - 1, complement);
if (j != -1) return new int[]{i + 1, j + 1};
}
return new int[0];
}
public static void main(String[] args) {
int[] result = twoSum(new int[]{2,7,11,15}, 9);
System.out.println(java.util.Arrays.toString(result)); // [1, 2]
}
}
Line Notes
while (left <= right) {Binary search loop condition
int mid = left + (right - left) / 2;Calculate mid index safely
if (arr[mid] == target) return mid;Found complement at mid
for (int i = 0; i < n; i++) {Iterate over array to find complement for each element
#include <iostream>
#include <vector>
using namespace std;
int binarySearch(const vector<int>& arr, int left, int right, int target) {
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) return mid;
else if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
vector<int> twoSumBinarySearch(vector<int>& numbers, int target) {
int n = numbers.size();
for (int i = 0; i < n; i++) {
int complement = target - numbers[i];
int j = binarySearch(numbers, i + 1, n - 1, complement);
if (j != -1) return {i + 1, j + 1};
}
return {};
}
int main() {
vector<int> nums = {2,7,11,15};
vector<int> res = twoSumBinarySearch(nums, 9);
cout << "[" << res[0] << ", " << res[1] << "]" << endl; // [1, 2]
return 0;
}
Line Notes
while (left <= right) {Binary search loop condition
int mid = left + (right - left) / 2;Calculate mid index safely
if (arr[mid] == target) return mid;Found complement at mid
for (int i = 0; i < n; i++) {Iterate over array to find complement for each element
function binarySearch(arr, left, right, target) {
while (left <= right) {
const mid = left + Math.floor((right - left) / 2);
if (arr[mid] === target) return mid;
else if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
function twoSumBinarySearch(numbers, target) {
const n = numbers.length;
for (let i = 0; i < n; i++) {
const complement = target - numbers[i];
const j = binarySearch(numbers, i + 1, n - 1, complement);
if (j !== -1) return [i + 1, j + 1];
}
return [];
}
// Test
console.log(twoSumBinarySearch([2,7,11,15], 9)); // [1, 2]
Line Notes
while (left <= right) {Binary search loop condition
const mid = left + Math.floor((right - left) / 2);Calculate mid index safely
if (arr[mid] === target) return mid;Found complement at mid
for (let i = 0; i < n; i++) {Iterate over array to find complement for each element
For each of the n elements, binary search takes O(log n), totaling O(n log n).
💡 For n=20, this means about 20 * 4.3 = 86 operations, better than brute force but slower than two pointers.
Interview Verdict: Accepted but less optimal than two pointers
Good alternative if two pointers are not obvious; still efficient but not best.