# Leetcode First-Bad-Version

#### 2022-07-09 09:52

> ##### Algorithms:
>
> #algorithm #binary_search
>
> ##### Data structures:
>
> #DS #array
>
> ##### Difficulty:
>
> #coding_problem #difficulty-easy
>
> ##### Additional tags:
>
> #leetcode
>
> ##### Revisions:
>
> N/A

##### Related topics:

##### Links:

- [Link to problem](https://leetcode.com/problems/first-bad-version/)

---

### 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. Implement a function to find the first bad version. You should minimize the number of calls to the API.

#### Examples

**Example 1:**

**Input:** n = 5, bad = 4
**Output:** 4
**Explanation:**
call isBadVersion(3) -> false
call isBadVersion(5) -> true
call isBadVersion(4) -> true
Then 4 is the first bad version.

**Example 2:**

**Input:** n = 1, bad = 1
**Output:** 1

#### Constraints

- `1 <= bad <= n <= 231 - 1`

### Thoughts

> [!summary]
> This is a #binary_search problem

Note that [[Leetcode First-Bad-Version#Constraints]], n can be 2\*\*31, which means there might be integer overflow.

To address that, according to [[Binary Search Algorithm#How to implement Binary search]], use `mid = l + (r - l) / 2`

In my first iteration,
I use a `first` variable to keep track of the first bad version.

Later I realized that by the definition of Bi-search, left boundary will converge to the first one.

### Solution

Second version, 0ms

```cpp
// The API isBadVersion is defined for you.
// bool isBadVersion(int version);

class Solution {
public:
  int firstBadVersion(int n) {
    // variant of BS
    // 1-indexed

    int r = n;
    int l = 1;
    int mid;

    do {
      mid = l + (r - l) / 2;

      if (isBadVersion(mid)) {
        // Search left
        r = mid - 1;
      } else {
        l = mid + 1;
      }
    } while (l <= r);

    return l;
  }
};
```

First iteration, 4ms

```cpp
// The API isBadVersion is defined for you.
// bool isBadVersion(int version);

class Solution {
public:
  int firstBadVersion(int n) {
    // variant of BS
    // 1-indexed

    int r = n;
    int l = 1;
    int mid;
    int first = n;

    do {
      mid = l + (r - l) / 2;

      if (isBadVersion(mid)) {
        first = min(n, mid);
        // Search left
        r = mid - 1;
      } else {
        l = mid + 1;
      }
    } while (l <= r);

    return first;
  }
};
```
