Il existe également un algorithme de temps linéaire et d'espace constant basé sur le partitionnement, qui peut être plus flexible si vous essayez de l'appliquer à des variantes du problème sur lesquelles l'approche mathématique ne fonctionne pas bien. Cela nécessite de muter le tableau sous-jacent et présente des facteurs constants pires que l'approche mathématique. Plus précisément, je pense que les coûts en termes du nombre total de valeurs et du nombre de doublons d sont respectivement O ( n log d ) et O ( d ) , bien que le prouver rigoureusement prendra plus de temps que je n'en ai actuellement .ndO(nlogd)O(d)
Algorithme
Commencez avec une liste de paires, où la première paire est la plage sur l'ensemble du tableau, ou si indexé 1.[(1,n)]
Répétez les étapes suivantes jusqu'à ce que la liste soit vide:
- Prenez et supprimez toute paire de la liste.(i,j)
- Trouvez le minimum et le maximum, et max , du sous-tableau noté.minmax
- Si , le sous-tableau se compose uniquement d'éléments égaux. Donnez ses éléments sauf un et ignorez les étapes 4 à 6.min=max
- Si , le sous-tableau ne contient aucun doublon. Ignorez les étapes 5 et 6.max−min=j−i
- Partitionnez le sous-tableau autour de , de sorte que les éléments jusqu'à un certain indiceksont plus petits que le séparateur et les éléments au-dessus de cet indice ne le sont pas.min+max2k
- Ajoutez et ( k + 1 , j ) à la liste.(i,k)(k+1,j)
Analyse cursive de la complexité temporelle.
Les étapes 1 à 6 prennent du temps , car la recherche du minimum et du maximum et le partitionnement peuvent être effectués en temps linéaire.O(j−i)
Chaque paire de la liste est soit la première paire, ( 1 , n ) , soit un enfant d'une paire pour laquelle le sous-tableau correspondant contient un élément en double. Il y a au plus d ⌈ log 2 n + 1 ⌉ de tels parents, car chaque parcours divise par deux la plage dans laquelle un doublon peut être, il y a donc au plus 2 d ⌈ log 2 n + 1 ⌉ au total lorsque des paires sont incluses sur des sous-réseaux sans doublons. À tout moment, la taille de la liste ne dépasse pas 2 jours(i,j)(1,n)d⌈log2n+1⌉2d⌈log2n+1⌉2d.
Considérez le travail pour trouver un double. Cela consiste en une séquence de paires sur une plage exponentiellement décroissante, donc le travail total est la somme de la séquence géométrique, ou . Cela produit un corollaire évident que le travail total pour les doublons d doit être O ( n d ) , qui est linéaire en n .O(n)dO(nd)n
Pour trouver une limite plus stricte, considérons le pire des cas de doublons répartis au maximum. Intuitivement, la recherche prend deux phases, l'une où le tableau complet est parcouru à chaque fois, en parties progressivement plus petites, et l'autre où les parties sont plus petites que donc seules les parties du tableau sont traversées. La première phase ne peut être quelogd enprofondeur, donc a coûtéO(nlogd), et la deuxième phase a coûtéO(n)parce que la superficie totale recherchée diminue à nouveau de façon exponentielle.ndlogdO(nlogd)O(n)