Algorithms · lab d'ingénierie
Résoudre Two Sum en C# : de la force brute aux tables de hachage
Un problème, deux approches. Échangez de la mémoire contre une recherche plus rapide et expliquez pourquoi la solution fonctionne.
// avant de commencer
- Tableaux, boucles, dictionnaires
- 1Comprendre
- 2Réfléchir
- 3Concevoir
- 4Implémenter
- 5Tester
- 6Améliorer
- 7Comparer à l'IA
01 / Comprendre le problème
Étant donné un tableau d'entiers et une cible, renvoyez deux indices distincts dont la somme des valeurs atteint la cible. Sans paire, renvoyez un tableau vide. On suppose ici que les valeurs et opérations tiennent dans un entier signé sur 32 bits.
nums = [2, 7, 11, 15], cible = 9 donne [0, 1]. Un même indice ne peut pas être réutilisé.
02 / Réfléchir avant de coder
Énumérez les paires possibles. Quelle information permettrait d'éviter une nouvelle recherche complète pour chaque valeur ?
Indice 1 : transformer la somme en recherche
Pour une valeur x, la valeur manquante vaut cible − x.
Indice 2 : mémoriser le passé
Conservez chaque valeur déjà rencontrée avec son indice. Cherchez le complément avant d'ajouter la valeur actuelle.
03 / Concevoir la solution
Parcourez le tableau de gauche à droite. Calculez le complément. S'il est déjà présent dans le dictionnaire, renvoyez son indice et l'indice actuel. Sinon, mémorisez la valeur actuelle.
04 / Implémenter
Révéler la force brute
public static int[] TwoSumBrute(int[] nums, int target)
{
for (int i = 0; i < nums.Length; i++)
for (int j = i + 1; j < nums.Length; j++)
if (nums[i] + nums[j] == target)
return new[] { i, j };
return Array.Empty<int>();
}Il existe n(n−1)/2 paires : temps O(n²), espace supplémentaire O(1), hors résultat.
Révéler la version avec dictionnaire
public static int[] TwoSum(int[] nums, int target)
{
var seen = new Dictionary<int, int>();
for (int i = 0; i < nums.Length; i++)
{
int complement = target - nums[i];
if (seen.TryGetValue(complement, out int previous))
return new[] { previous, i };
seen[nums[i]] = i;
}
return Array.Empty<int>();
}Temps attendu O(n), espace O(n). Les opérations du dictionnaire sont en O(1) attendu, pas garanties dans tous les cas. Chercher avant d'insérer évite de réutiliser le même indice.
05 / Tester
TwoSum(new[] { 2, 7, 11, 15 }, 9); // [0, 1]
TwoSum(new[] { 3, 3 }, 6); // [0, 1]
TwoSum(new[] { -3, 4, 3 }, 0); // [0, 2]
TwoSum(new[] { 1 }, 2); // []
TwoSum(Array.Empty<int>(), 0); // []06 / Améliorer
Définissez le comportement pour une entrée nulle et le dépassement d'entier. Pour des valeurs int sans restriction, calculez le complément avec long puis vérifiez avant conversion. Documentez la paire renvoyée lorsque plusieurs solutions existent.
07 / Comparer avec l'IA
Faites résoudre le même contrat à un assistant. Vérifiez les doublons, la réutilisation d'indice, le dépassement et les annonces de complexité. Le succès du premier exemple n'est pas une preuve.
Pause. Essayez d'abord vous-même.
Ouvrez votre éditeur et accordez-vous quinze minutes honnêtes. Revenez ensuite ouvrir un indice à la fois.
hint 1/2 Révéler l'indice
Calculez cible moins la valeur actuelle.
hint 2/2 Révéler l'indice
Mémorisez les valeurs précédentes dans un dictionnaire.