Find the First Bad Version in a Monotonic Release History
Company: Qualcomm
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Overview: Find the earliest bad entry in a monotonic release history, returning -1 when every version is good. This compact coding prompt tests boundary-safe binary search, empty and all-good inputs, first-element failures, loop invariants, and logarithmic performance on histories with up to a million versions.
Constraints
- 0 <= len(bad) <= 1_000_000
- Every element of bad is a boolean: True or False.
- bad is monotonic: no False appears at any index after a True, so bad always has the form False*, True*.
- The empty log is permitted by the lower bound 0 <= len(bad); it contains no broken release and returns -1.
- The return value is either the sentinel -1 or an index in [0, len(bad) - 1], so it always lies in [-1, 999_999]. Every value and every intermediate index therefore fits comfortably in a 32-bit signed integer -- int is sufficient in Java and C++ -- and nothing comes anywhere near 2^53.
Examples
Input: ([],)
Expected Output: -1
Input: ([False],)
Expected Output: -1
Hints
- Monotonicity means the log is already sorted: every False sits before every True. That is exactly the precondition a search that halves its range needs.
- Instead of asking "which entry is broken?", ask "is the earliest broken release at or before index i?". That predicate is False on a prefix of the log and True on the rest, so you can decide which half to discard from a single lookup.
- Carry the best (smallest) broken index you have seen so far. Landing on a broken release means you can record it and keep searching strictly to its left; landing on a working one means everything to the left works too. If you finish without ever recording an index, the answer is the sentinel.