J'ai l'algorithme suivant qui trouve les doublons et les supprime:
public static int numDuplicatesB(int[] arr) {
Sort.mergesort(arr);
int numDups = 0;
for (int i = 1; i < arr.length; i++) {
if (arr[i] == arr[i - 1]) {
numDups++;
} }
return numDups;
}
J'essaie de trouver la pire complexité temporelle de cette situation. Je sais que mergesort est nlog(n)
, et dans ma boucle for, j'itère sur l'ensemble des données afin que cela compte comme n
. Je ne sais pas quoi faire de ces chiffres. Dois-je simplement les additionner ensemble? Si je devais faire ça, comment ferais-je?
O(n) + O(n log(n)) = O(n log(n))
Pour la complexité de Big O, vous ne vous souciez que du terme dominant. n log(n)
domine n
c'est donc le seul terme qui vous intéresse.
Raisonnons notre chemin et rappelons-nous la définition de O
. Celui que je vais utiliser est pour la limite à l'infini.
Vous avez raison de dire que vous effectuez deux opérations avec les limites asymptotiques correspondantes de O(n)
et O(nlog(n))
mais les combiner en une seule limite n'est pas aussi simple que d'ajouter les deux fonctions. Vous savez que votre fonction prend au moins O(n)
temps et également au moins O(nlog(n))
temps. Donc vraiment la classe de complexité de votre fonction est l'union de O(n)
et O(nlog(n))
mais O(nlog(n))
est un surensemble de O(n)
donc vraiment c'est juste O(nlog(n))
.
Si vous deviez l'exposer à la main, cela ressemblerait à peu près à ceci:
Supposons que le temps total soit: a n + b n log (n), où a et b sont des constantes (en ignorant les termes d'ordre inférieur).
Lorsque n va à l'infini (a n + b n log (n))/n log (n) -> a/log (n) + b -> b
Le temps total est donc O (b n log (n)) = O (n log (n)).
Commençons par la définition de O ():
O (n log n) signifie "inférieur à C n log n, si n est grand".
O (n) signifie "inférieur à D n, si n est grand".
Si vous ajoutez les deux, le résultat est inférieur à C n log n + D n <C n log n + D n log n <(C + D) n log n = O (n log n).
En général, si f (n)> C g (n) pour les grands n et certains C> 0, alors O (f (n)) + O (g (n)) = O (f (n)). Et après avoir fait quelques cas en utilisant la définition de O (), vous saurez ce que vous pouvez et ne pouvez pas faire.
La grande notation O est définie comme un ensemble:
Donc contient toutes les fonctions qui sont - à partir d'un grand point arbitraire - toujours plus petit que g.
Maintenant, quand vous avez une fonction qui est en puis exécutez un autre qui augmente plus lentement que g, il augmente certainement plus lentement que 2g. Donc, exécuter quelque chose de plus lent que g ne changera pas la classe de complexité.
Plus formellement:
Vous pouvez facilement le prouver.
TL; DR
Il est encore