Aller au contenu
  1. Algorithmes & Structures de données/
#22 Binary Search Facile 2 min de lecture

First Bad Version

Les versions 1..N d’un produit se suivent ; à partir d’une certaine version, toutes sont « mauvaises ». Une API isBadVersion(v) te répond. Trouve la PREMIÈRE mauvaise version en minimisant les appels à l’API.

🐻 Vocabulaire pas clair ? Consultez le glossaire algo.

C’est quoi le problème, en clair ? #

Une entreprise sort des versions 1, 2, 3… d’un produit, et à partir d’une certaine version, toutes celles qui suivent sont défectueuses. Vous disposez d’un testeur qui vous répond « bonne » ou « mauvaise » pour une version donnée, mais chaque test prend du temps : vous devez trouver la toute première version cassée en testant le moins de fois possible. C’est comme chercher la page où un livre commence à avoir des pages déchirées : plutôt que de tourner les pages une par une, vous l’ouvrez au milieu et vous décidez de quel côté continuer à chercher.

L’idée clé #

Le tableau des réponses ressemble à [bon, bon, …, bon, MAUVAIS, mauvais, …] : une frontière à localiser = recherche binaire sur la réponse. Si mid est mauvais, la première mauvaise est à mid ou avant ; sinon elle est strictement après. On resserre jusqu’à ce que left == right.

Pourquoi cette solution ? #

C’est la variante « chercher la frontière » de la recherche binaire, différente du « chercher une valeur exacte » ( Binary Search) : ici right = mid (et non mid - 1) car mid reste candidat. Maîtriser cette nuance d’invariant évite les bugs off-by-one — la cause n°1 d’échec sur ce type de question.

Solution Java #

public class Solution extends VersionControl {
    public int firstBadVersion(int n) {
        int left = 1, right = n;

        while (left < right) {
            int mid = left + (right - left) / 2;

            if (isBadVersion(mid)) {
                right = mid;     // mid est peut-etre LA premiere mauvaise : on la garde
            } else {
                left = mid + 1;  // mid est bonne : la frontiere est strictement apres
            }
        }
        // left == right : la premiere mauvaise version
        return left;
    }
}

Complexité #

Temps O(log N) : l’intervalle est divisé par deux à chaque appel API. Espace O(1).