Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
First Bad Version in Python
In software development, when a version fails quality checks, all subsequent versions are also considered bad since they're built upon the faulty version. The First Bad Version problem asks us to find the earliest bad version efficiently using binary search.
We have versions numbered from 1 to n, and an API function isBadVersion(version) that returns True if the version is bad, False otherwise. Our goal is to find the first bad version with minimum API calls.
Algorithm Overview
We use binary search to efficiently locate the first bad version ?
- If n < 2, return n (edge case)
- Use binary search with left and right pointers
- Check middle version and adjust search range accordingly
- Continue until we find the transition point from good to bad
Implementation
# Global variable to simulate the first bad version
first_bad = 0
def isBadVersion(version):
"""API function that returns True if version is bad"""
if version >= first_bad:
return True
return False
class Solution:
def firstBadVersion(self, n):
"""Find the first bad version using binary search"""
if n < 2:
return n
left = 1
right = n
while left <= right:
mid = (left + right) // 2
# If mid is bad but mid-1 is good, we found the first bad version
if isBadVersion(mid) and not isBadVersion(mid - 1):
return mid
# If mid-1 is also bad, search in left half
elif isBadVersion(mid - 1):
right = mid - 1
# If mid is good, search in right half
else:
left = mid + 1
# Test the solution
first_bad = 4 # Set version 4 as the first bad version
solution = Solution()
result = solution.firstBadVersion(5)
print(f"First bad version: {result}")
First bad version: 4
How It Works
The algorithm works by repeatedly dividing the search space in half ?
- Initial setup: Set left = 1, right = n
- Find middle: Calculate mid = (left + right) // 2
-
Check conditions:
- If mid is bad AND mid-1 is good ? found first bad version
- If mid-1 is also bad ? search left half (right = mid-1)
- If mid is good ? search right half (left = mid+1)
- Repeat until first bad version is found
Example Walkthrough
For versions [1, 2, 3, 4, 5] where version 4 is the first bad ?
# Simulate the search process
first_bad = 4
solution = Solution()
# Step-by-step visualization
versions = [1, 2, 3, 4, 5]
print("Versions:", versions)
print("Bad versions start from:", first_bad)
# Check each version
for v in versions:
status = "BAD" if isBadVersion(v) else "GOOD"
print(f"Version {v}: {status}")
print(f"\nFirst bad version found: {solution.firstBadVersion(5)}")
Versions: [1, 2, 3, 4, 5] Bad versions start from: 4 Version 1: GOOD Version 2: GOOD Version 3: GOOD Version 4: BAD Version 5: BAD First bad version found: 4
Time and Space Complexity
- Time Complexity: O(log n) - binary search reduces search space by half each iteration
- Space Complexity: O(1) - only using constant extra space for variables
Conclusion
The First Bad Version problem is efficiently solved using binary search, reducing time complexity from O(n) to O(log n). The key insight is leveraging the sorted nature of bad versions to eliminate half the search space in each iteration.
