First Bad Version
First Bad Version: Mastering Binary Search
Welcome back to codinginterview.net. By now, you have likely traversed arrays and manipulated pointers. Now, it is time to tackle a fundamental algorithm that every software engineer must know by heart: Binary Search. The "First Bad Version" problem is a classic gauge of whether a candidate understands how to drastically reduce search spaces. By the end of this guide, optimizing search queries and avoiding common integer overflow traps will be second nature to you.
1. Understanding the Problem
You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad.
Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which causes all the following ones to be bad. You are given an API bool isBadVersion(version) which returns whether version is bad. Your goal is to implement a function to find the first bad version while minimizing the number of calls to the API.
The Core Constraint (The Trap):
API calls are expensive. If you have millions of versions, checking every single one individually will result in a "Time Limit Exceeded" error. Furthermore, when calculating the midpoint of your search space, a naive mathematical approach can cause a disastrous integer overflow in statically typed languages.
2. The Naive Approach: Linear Scan
The most intuitive way to solve this is to test each version one by one, starting from version 1. You call isBadVersion(1), then isBadVersion(2), and so on, until the API returns True.
Trade-off Analysis
While this logic guarantees you will find the first bad version, it is highly inefficient:
- Time Complexity: O(N) — In the worst-case scenario (the very last version is the first bad one), you make N calls to the API. If N is 2 billion, your program will grind to a halt.
- Space Complexity: O(1) — No extra memory is used.
3. The Optimal Approach: Binary Search (O(log N) Time)
To pass a senior-level technical interview, we want to achieve an O(log N) time complexity. Because the versions are sorted and the "badness" propagates (e.g., Good, Good, Bad, Bad, Bad), this is a perfect candidate for Binary Search.
Imagine looking for a word in a physical dictionary. You do not read every page from the beginning. You open it to the middle. If the word you are looking for comes alphabetically before the page you are on, you tear the book in half and throw away the right side. You repeat this process, constantly halving your search space, until you find the exact word.
We apply this exact logic to our versions. We check the middle version. If it is bad, the first bad version must be this one or somewhere to its left. If it is good, the first bad version must be to its right.
4. The Logic Step-by-Step
- Initialize Pointers: Set a
leftpointer to 1 (the first version) and arightpointer ton(the latest version). - Traverse the Search Space: Create a loop that continues as long as
left < right.- Calculate the Midpoint: Instead of doing
(left + right) / 2, useleft + (right - left) / 2. This mathematically yields the same result but prevents integer overflow ifleftandrightare massive numbers close to the 32-bit integer limit. - The API Check: Call
isBadVersion(mid). - If True (Bad Version): We know the current version is bad, but we don't know if it's the first one. The answer is either
midor something before it. Move therightpointer tomid. - If False (Good Version): We know this version is good, so everything before it is also good. The first bad version must be strictly after
mid. Move theleftpointer tomid + 1.
- Calculate the Midpoint: Instead of doing
- When the loop breaks (
left == right), the pointers have converged exactly on the first bad version. Returnleft.
5. Complexity Analysis
- Time Complexity: O(log N) — The search space is halved with every iteration. For 2 billion versions, it takes a maximum of only ~31 API calls to find the exact target. A massive improvement over O(N)!
- Space Complexity: O(1) — We only use two pointers, regardless of how large the version history is.
6. Code Implementations
Expand the sections below to see the optimal O(log N) "Binary Search" implementations across different languages.
View Python Solution
# The isBadVersion API is already defined for you.
# def isBadVersion(version: int) -> bool:
class Solution:
def firstBadVersion(self, n: int) -> int:
left = 1
right = n
while left < right:
mid = left + (right - left) // 2
if isBadVersion(mid):
# The first bad version is either mid or to the left
right = mid
else:
# The first bad version is strictly to the right
left = mid + 1
# left and right converge to the first bad version
return left
View Java Solution
/* The isBadVersion API is defined in the parent class VersionControl.
boolean isBadVersion(int version); */
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int left = 1;
int right = n;
while (left < right) {
// Prevent integer overflow trap!
int mid = left + (right - left) / 2;
if (isBadVersion(mid)) {
right = mid; // First bad is mid or before
} else {
left = mid + 1; // First bad is strictly after mid
}
}
return left;
}
}
View C++ Solution
// The API isBadVersion is defined for you.
// bool isBadVersion(int version);
class Solution {
public:
int firstBadVersion(int n) {
int left = 1;
int right = n;
while (left < right) {
// Safe way to calculate midpoint without overflow
int mid = left + (right - left) / 2;
if (isBadVersion(mid)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
};
7. Conclusion: You Are Ready
Congratulations, you have successfully implemented a customized Binary Search! Recognizing when a dataset has a "sorted" nature (even if it is just a sequence of booleans like False, False, True, True) is the key to unlocking O(log N) speeds. Furthermore, understanding the integer overflow trap associated with (left + right) / 2 demonstrates the kind of low-level operational awareness that top tech companies look for. Keep this Binary Search template handy, as it is the foundation for dozens of other advanced algorithms!