Binary Search on Answer Technique in DSA C - Time & Space Complexity
We want to understand how fast the binary search on answer technique works when finding a solution by guessing and checking.
How does the number of guesses grow as the range of possible answers grows?
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 (canDo(mid)) {
high = mid;
} else {
low = mid + 1;
}
}
return low;
}
// canDo(mid) checks if mid is a valid answer
This code tries to find the smallest valid answer by repeatedly guessing the middle value and narrowing the search range.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that halves the search range each time.
- How many times: The loop runs until the range is reduced to zero, about log2 of the initial range size.
Each guess cuts the search space roughly in half, so the number of guesses grows slowly even if the range grows large.
| Input Size (range) | Approx. Operations (guesses) |
|---|---|
| 10 | About 4 guesses |
| 100 | About 7 guesses |
| 1000 | About 10 guesses |
Pattern observation: Doubling the range adds only one more guess, showing slow growth.
Time Complexity: O(log n)
This means the number of steps grows slowly, doubling the range only adds one more step.
[X] Wrong: "The loop runs n times because it checks every number in the range."
[OK] Correct: The loop does not check every number; it cuts the range in half each time, so it runs much fewer times.
Understanding this technique shows you can solve problems efficiently by smart guessing, a skill valued in many coding challenges.
"What if the canDo() check took linear time instead of constant time? How would the overall time complexity change?"
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: Explain the technique
We repeatedly pick a middle value in the answer range and check if it satisfies the problem's conditions, then narrow the range accordingly.Final Answer:
Searching for the answer by repeatedly dividing the search space based on feasibility -> Option AQuick Check:
Binary Search on Answer = Divide and check feasibility [OK]
- Confusing it with normal binary search on arrays
- Trying to apply without a feasibility check
- Assuming answer must be in the input array
low and high?Solution
Step 1: Identify the binary search loop structure
Binary search uses a while loop with condition low <= high to narrow the search space.Step 2: Confirm calculation of mid and feasibility check
Mid is calculated as (low + high) / 2 inside the loop, then feasibility is checked to adjust low or high.Final Answer:
while (low <= high) { int mid = (low + high) / 2; /* check feasibility */ } -> Option DQuick Check:
Binary search loop = while(low <= high) [OK]
- Using for loop instead of while
- Incorrect loop condition like low < high
- Not updating low or high inside loop
m subarrays:
int canSplit(int* arr, int n, int m, int maxLoad) {
int count = 1, currentSum = 0;
for (int i = 0; i < n; i++) {
if (arr[i] > maxLoad) return 0;
if (currentSum + arr[i] > maxLoad) {
count++;
currentSum = arr[i];
} else {
currentSum += arr[i];
}
}
return count <= m;
}
int binarySearchAnswer(int* arr, int n, int m) {
int low = 0, high = 0;
for (int i = 0; i < n; i++) high += arr[i];
int ans = high;
while (low <= high) {
int mid = (low + high) / 2;
if (canSplit(arr, n, m, mid)) {
ans = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
return ans;
}
int main() {
int arr[] = {7, 2, 5, 10, 8};
int n = 5, m = 2;
printf("%d", binarySearchAnswer(arr, n, m));
return 0;
}
What is the output of this program?Solution
Step 1: Understand the problem and code logic
The code finds the minimum maximum load to split the array into 2 subarrays so that the largest sum among subarrays is minimized.Step 2: Dry run with given array
Possible splits: - [7,2,5] and [10,8] max sums 14 and 18 -> max 18 - [7,2] and [5,10,8] max sums 9 and 23 -> max 23 - [7] and [2,5,10,8] max sums 7 and 25 -> max 25 Minimum max load is 18.Final Answer:
18 -> Option AQuick Check:
Minimum max load = 18 [OK]
- Choosing sum of all elements as answer
- Not considering feasibility function logic
- Confusing minimum max load with total sum
int canComplete(int* tasks, int n, int m, int maxTime) {
int count = 1, currentTime = 0;
for (int i = 0; i < n; i++) {
if (tasks[i] > maxTime) return 0;
if (currentTime + tasks[i] >= maxTime) {
count++;
currentTime = tasks[i];
} else {
currentTime += tasks[i];
}
}
return count <= m;
}Solution
Step 1: Analyze the feasibility condition
The condition currentTime + tasks[i] >= maxTime causes a new segment even when sum equals maxTime, which is incorrect.Step 2: Correct the condition
It should be currentTime + tasks[i] > maxTime to start a new segment only when sum exceeds maxTime.Final Answer:
The condition should be currentTime + tasks[i] > maxTime, not >= maxTime -> Option BQuick Check:
Use > for splitting condition, not >= [OK]
- Using >= causes extra segments
- Starting count from 0 instead of 1
- Returning wrong comparison for count and m
m units. Given an array trees[] of heights, which approach correctly applies binary search on answer to solve this problem?Solution
Step 1: Define the search space for cutting height
The cutting height can vary from 0 to the tallest tree height.Step 2: Check feasibility by summing wood collected at mid height
For a candidate mid, sum wood = sum of (tree height - mid) if positive; check if sum >= m.Step 3: Adjust search space based on feasibility
If enough wood is collected, try higher cut (low = mid + 1) to minimize cut height; else lower cut (high = mid - 1).Final Answer:
Set low = 0, high = max height in trees; check if cutting at mid yields enough wood; adjust low or high accordingly -> Option CQuick Check:
Binary search on cut height range with feasibility check [OK]
- Binary searching on sorted array instead of answer range
- Using sum of all trees without cutting logic
- Confusing indices with answer values
Ready to prove it?
Pass the test and this pattern moves unknown
