Bases & algorithmique · 6 mondes · 18 étapes
Algorithmique
Apprendre à penser un problème, en Python, dans le navigateur.
Progression
0 %
0/18 étapes terminées
Avancé · 12 min de lecture
Résoudre un problème inconnu
La méthode des entretiens techniques, et du travail réel
1Définition
Face à un énoncé nouveau, la performance ne vient pas de la vitesse de frappe mais d'une méthode : clarifier, chercher le motif connu, écrire une version naïve, mesurer, puis optimiser le vrai goulot. C'est aussi, littéralement, la grille de notation d'un entretien technique.
2Principes fondamentaux
01
Clarifier avant de coder
Quelle taille de données ? Des doublons ? Des valeurs négatives ? La liste est-elle triée ? Chaque réponse élimine ou ouvre un algorithme.
02
La version naïve est un livrable
Une solution en O(n²) qui marche bat une solution en O(n) inachevée. On l'écrit, on la valide, puis on l'améliore.
03
Chercher le motif
Recherche, tri, comptage par dictionnaire, deux pointeurs, récursivité, mémoïsation : la majorité des problèmes est une variante d'un de ces six motifs.
04
Dire son raisonnement à voix haute
En entretien comme en revue de code, le raisonnement compte davantage que la solution : il montre comment tu réagiras face au problème suivant.
3Exemples pratiques
Le même problème, trois niveaux
1# « Existe-t-il deux nombres dont la somme fait la cible ? »2 3# 1. Naïf, O(n²) : toutes les paires4for i in range(len(v)):5 for j in range(i + 1, len(v)):6 if v[i] + v[j] == cible:7 ...8 9# 2. Deux pointeurs, O(n log n) : exige un tri10v = sorted(v)11g, d = 0, len(v) - 112while g < d:13 s = v[g] + v[d]14 if s == cible: break15 elif s < cible: g += 116 else: d -= 117 18# 3. Dictionnaire, O(n) : un seul parcours19vus = set()20for x in v:21 if cible - x in vus:22 ...23 vus.add(x)Trois solutions justes, trois complexités. La troisième vient du réflexe « je cherche quelque chose dans une boucle, donc j'indexe ».
Vérifier avec des assertions
1def paire(v, cible):2 vus = set()3 for x in v:4 if cible - x in vus:5 return True6 vus.add(x)7 return False8 9assert paire([10, 25, 75], 100) is True10assert paire([], 100) is False # liste vide11assert paire([50], 100) is False # un seul élément12print("Tests OK")Trois assertions écrites avant de livrer : le cas normal, le cas vide, le cas unique. C'est le minimum professionnel.
4Erreurs courantes
Coder avant d'avoir compris
À éviter
# taper immédiatement, corriger au fur et à mesureÀ faire
# reformuler l'énoncé en une phrase, lister les cas limites, puis coderPourquoi : Une minute de reformulation économise dix minutes de code jeté.
Optimiser le mauvais endroit
À éviter
# raccourcir une boucle de 10 tours dans une fonction appelée une foisÀ faire
# instrumenter, trouver la boucle réellement coûteuse, l'attaquerPourquoi : Sans mesure, l'intuition se trompe presque toujours sur l'emplacement du goulot.
5Subtilités à connaître
- ◆Beaucoup d'énoncés cachent leur contrainte décisive dans une phrase anodine : « la liste est déjà triée » ouvre la dichotomie et les deux pointeurs.
- ◆Quand les mêmes sous-problèmes reviennent, le mot-clé à retenir est programmation dynamique : mémoïsation descendante, ou tableau construit de bas en haut.
- ◆Un algorithme qui tient en mémoire compte autant qu'un algorithme rapide : sur de très grands volumes, on travaille en flux, ligne par ligne.
6Techniques d'expert
Mesurer avant d'optimiser
Un compteur d'opérations, ou time.perf_counter(), dit où part le temps. Sans mesure, on optimise au hasard.
import time debut = time.perf_counter()resultat = traiter(donnees)print(round(time.perf_counter() - debut, 4), "s")Mémoïsation en une ligne
functools.lru_cache fait le travail du dictionnaire de cache, sans le code.
from functools import lru_cache @lru_cache(maxsize=None)def fib(n): if n <= 1: return n return fib(n - 1) + fib(n - 2)Valider contre une version naïve
Quand on remplace un algorithme par un plus rapide, on garde l'ancien et on compare les deux sur des données aléatoires : c'est le test le plus efficace qui existe.
import random for _ in range(200): v = [random.randint(0, 50) for _ in range(10)] assert rapide(v) == naif(v)print("Les deux versions concordent")7Sur le terrain
- Les entretiens techniques des grandes entreprises évaluent exactement cette méthode : clarification, motif, complexité annoncée, cas limites.
- En production, la plupart des lenteurs viennent d'une recherche répétée dans une liste ou d'une requête dans une boucle — jamais d'un manque de micro-optimisation.
- Les bibliothèques standard sont écrites par des équipes qui ont passé des années sur ces algorithmes : les connaître sert surtout à savoir laquelle appeler.
8Vérifie ta compréhension
Question 1/3
Score 0
Première chose à faire devant un énoncé inconnu ?
Envie d'essayer ? Ouvre le Labo et recopie les exemples pour les modifier.