Binary Search on Answer Technique in DSA C++ - Time & Space Complexity
We want to understand how fast the binary search on answer technique finds the correct answer.
How does the number of steps grow when the search range gets bigger?
Analyze the time complexity of the following code snippet.
int binarySearchOnAnswer(int low, int high) {
while (low <= high) {
int mid = low + (high - low) / 2;
if (check(mid)) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return low;
}
This code tries to find the smallest value that satisfies a condition by repeatedly checking the middle of the current range.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that halves the search range each time.
- How many times: About log2 of the size of the search range.
Each step cuts the search range roughly in half, so the number of steps grows slowly as the range grows.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 4 steps |
| 100 | About 7 steps |
| 1000 | About 10 steps |
Pattern observation: Doubling the input size adds only one extra step.
Time Complexity: O(log n)
This means the number of steps grows slowly, making the search very efficient even for large ranges.
[X] Wrong: "The binary search on answer takes linear time because it checks many values."
[OK] Correct: It does not check every value; it smartly halves the search range each time, reducing steps drastically.
Understanding this technique shows you can solve problems efficiently by narrowing down answers quickly, a skill valued in many coding challenges.
"What if the check function takes linear time itself? How would that affect the overall time complexity?"
Practice
Binary Search on Answer technique?Solution
Step 1: Understand the problem context
Binary Search on Answer is used when the answer lies within a range and we can check feasibility for a candidate answer.Step 2: Apply binary search on the answer range
We repeatedly pick a middle value and check if it satisfies the problem's conditions, narrowing the search space accordingly.Final Answer:
Searching for the answer by repeatedly dividing the search space based on feasibility -> Option AQuick Check:
Binary Search on Answer = feasibility check [OK]
- Confusing it with normal binary search on arrays
- Not checking feasibility properly
- Trying to apply it on unsorted data without a valid range
low to high in C++?Solution
Step 1: Identify the correct loop condition
Binary search typically uses a loop with conditionlow < highto avoid infinite loops and handle edge cases.Step 2: Calculate mid safely
Usingmid = low + (high - low) / 2prevents integer overflow compared to(low + high) / 2.Final Answer:
while (low < high) { int mid = low + (high - low) / 2; } -> Option CQuick Check:
Safe mid calculation with proper loop [OK]
- Using <= in loop causing infinite loops
- Calculating mid as (low + high)/2 risking overflow
- Using for loop instead of while for binary search
k subarrays:bool canDivide(const vector<int>& arr, int k, int maxLoad) {
int currentSum = 0, count = 1;
for (int num : arr) {
if (num > maxLoad) return false;
if (currentSum + num > maxLoad) {
count++;
currentSum = num;
} else {
currentSum += num;
}
}
return count <= k;
}
int binarySearchAnswer(const vector<int>& arr, int k) {
int low = 0, high = 0;
for (int num : arr) high += num;
while (low < high) {
int mid = low + (high - low) / 2;
if (canDivide(arr, k, mid)) high = mid;
else low = mid + 1;
}
return low;
}
int main() {
vector<int> arr = {7, 2, 5, 10, 8};
int k = 2;
cout << binarySearchAnswer(arr, k) << endl;
}What is the output of this program?
Solution
Step 1: Understand the problem and code
The code finds the minimum maximum sum when dividing the array into 2 subarrays. The total sum is 7+2+5+10+8=32.Step 2: Trace binary search on answer
Check mid values and feasibility:
- mid=16: canDivide returns true (possible, e.g., subarrays sums 14 and 18)
- mid=15: canDivide returns true (possible, e.g., subarrays sums 14 and 15)
- mid=14: canDivide returns false (cannot split into 2 with max sum 14)
Binary search narrows down to 15 as minimum max load.Final Answer:
15 -> Option AQuick Check:
Minimum max load = 15 [OK]
- Not checking if single element > mid
- Incorrectly updating low and high
- Misunderstanding feasibility function
D days using binary search on answer. Identify the bug:bool canShip(const vector<int>& weights, int D, int capacity) {
int days = 1, currentLoad = 0;
for (int w : weights) {
if (w > capacity) return false;
if (currentLoad + w > capacity) {
days++;
currentLoad = w;
} else {
currentLoad += w;
}
}
return days <= D;
}
int shipWithinDays(const vector<int>& weights, int D) {
int low = 0, high = accumulate(weights.begin(), weights.end(), 0);
while (low <= high) {
int mid = low + (high - low) / 2;
if (canShip(weights, D, mid)) high = mid - 1;
else low = mid + 1;
}
return low;
}Solution
Step 1: Analyze initial search range
Low should start at the maximum single package weight because capacity cannot be less than the heaviest package.Step 2: Identify impact of wrong low value
Starting low at 0 causes unnecessary checks and may cause incorrect results or longer runtime.Final Answer:
The initial value of low should be the maximum weight in the array, not 0 -> Option DQuick Check:
Low = max(weights) [OK]
- Starting low at 0 instead of max element
- Using <= in loop causing off-by-one errors
- Ignoring edge cases with large weights
n tasks using m machines, where each machine can complete one task in a fixed time given by array times. You can assign multiple tasks to a machine but tasks are done sequentially. Using binary search on answer, which approach correctly finds the minimum time to finish all tasks?Choose the correct approach:
Solution
Step 1: Define search space for binary search
The minimum time is 0 and maximum time is max machine time * n tasks (worst case all tasks on slowest machine).Step 2: Check feasibility at mid time
Calculate total tasks all machines can complete in mid time by summing floor(mid / times[i]). If total tasks >= n, mid time is feasible.Step 3: Narrow search space
If feasible, try smaller time by setting high = mid; else low = mid + 1.Final Answer:
Binary search on time range from 0 to max(times) * n, and check if total tasks done by all machines in mid time is at least n -> Option BQuick Check:
Binary search on time with feasibility check [OK]
- Binary searching on machines instead of time
- Not summing tasks correctly for feasibility
- Ignoring sequential task processing per machine
Ready to prove it?
Pass the test and this pattern moves unknown
