First Bad Version (LeetCode 278) asks you to find the earliest version in 1..n that is bad, given that versions are monotonic: once one version is bad, every later version is bad too. Imagine a bad commit that slips into your project — every build after it fails, and you want the exact one that introduced the break. You can only learn whether a version is bad by calling isBad(version), and each call is expensive (picture a full CI build), so the goal is to find the boundary with as few calls as possible. That "locate the boundary in a sorted range" shape is a textbook binary search.
firstBadVersion(n, isBad)
// n — how many versions there are, labelled 1..n
// isBad — (version: number) => boolean, true when that version is bad.
// Monotonic: if isBad(k) is true, then isBad(k + 1) ... isBad(n) are all true.
// returns the smallest version number for which isBad is true
firstBadVersion(5, (v) => v >= 4); // 4 — versions 1-3 good, 4-5 bad
firstBadVersion(5, (v) => v >= 1); // 1 — every version is bad
firstBadVersion(5, (v) => v >= 5); // 5 — only the last version is bad
isBad returns true it never returns false again. That ordering is exactly what makes binary search valid.1..n is bad, so an answer always exists; you never return "not found".O(log n) calls to isBad, not O(n). Each call models an expensive check, so the number of calls is the real cost.isBad is the only oracle — you cannot inspect a version directly. Calling isBad(version) is the one and only way to learn whether it is good or bad.