Imaginez une IA surveillant un flux vidéo en direct pour détecter des activités suspectes. Elle ne peut pas revisionner l'intégralité de l'enregistrement chaque seconde - elle doit faire glisser une fenêtre d'attention sur le flux, en conservant juste assez de contexte. C'est exactement ce que font les patterns two pointers et sliding window pour les données séquentielles.
Ces deux techniques transforment des parcours brute-force en O(n²) en élégants parcours en O(n).
Placez deux références dans une séquence et déplacez-les selon une règle. Il existe deux variantes principales.
Placez un pointeur à chaque extrémité et déplacez-les vers l'intérieur. Idéal pour les données triées.
Problème classique - Pair Sum : Étant donné un tableau trié, trouvez deux nombres dont la somme correspond à une cible.
function pairSum(arr, target):
left = 0
right = arr.length - 1
while left < right:
sum = arr[left] + arr[right]
if sum == target: return (left, right)
if sum < target: left += 1
else: right -= 1
return null
Comme le tableau est trié, déplacer left vers la droite augmente la somme, et déplacer right vers la gauche la diminue - garantissant qu'aucune paire valide n'est manquée.
Les deux pointeurs avancent, mais à des vitesses différentes. Utile pour le partitionnement ou la détection de cycles.
Exemple - Supprimer les doublons en place : Un pointeur lent marque la position d'écriture ; un pointeur rapide parcourt en avance.
function removeDuplicates(arr):
slow = 0
for fast in 1..arr.length - 1:
if arr[fast] != arr[slow]:
slow += 1
arr[slow] = arr[fast]
return slow + 1
Sign in to join the discussion
Dans la technique two pointers convergents sur un tableau trié, que faut-il faire lorsque la somme actuelle est inférieure à la cible ?
Une sliding window maintient une sous-séquence contiguë de taille k (fixe) ou de longueur variable, en mettant à jour les agrégats de manière incrémentale plutôt que de les recalculer entièrement.
Faites glisser une fenêtre de exactement k éléments sur le tableau.
Exemple - Somme maximale de k éléments consécutifs :
function maxSubarraySum(arr, k):
windowSum = sum(arr[0..k-1])
best = windowSum
for i in k..arr.length - 1:
windowSum += arr[i] - arr[i - k]
best = max(best, windowSum)
return best
À chaque étape, on ajoute le nouvel élément entrant dans la fenêtre et on soustrait celui qui en sort - O(1) par déplacement.
Élargissez la fenêtre pour inclure plus de données, puis réduisez-la lorsqu'une contrainte est violée.
Exemple - Plus longue sous-chaîne sans caractères répétés :
function longestUnique(s):
seen = {}
left = 0
best = 0
for right in 0..s.length - 1:
if s[right] in seen and seen[s[right]] >= left:
left = seen[s[right]] + 1
seen[s[right]] = right
best = max(best, right - left + 1)
return best
| Pattern | Cas d'usage en IA | |---------|------------------| | Fenêtre fixe | Détection d'anomalies sur les k dernières lectures de capteurs | | Fenêtre variable | Trouver le plus court extrait de texte contenant tous les mots-clés d'une requête (moteurs de recherche) | | Pointeurs convergents | Vérifications efficaces du plus proche voisin dans des dimensions d'embeddings triées | | Pointeurs même direction | Fusion de listes de résultats triées provenant de multiples modèles de retrieval |
Quel pattern choisiriez-vous pour trouver le plus petit sous-tableau dont la somme dépasse une valeur donnée ?
Quelle est la complexité temporelle typique obtenue en convertissant une boucle imbriquée brute-force en solution two pointers ou sliding window ?