InSPIRE par diverses solutions et commentaires ci-dessus, environ 20 % - 50 % plus rapide dans mes tests (simples) que le plus rapide d'entre eux (bien que je sois sûr qu'il pourrait être rendu plus rapide), et gérant tous les cas de coin mentionnés (nombres non positifs, doublons et liste vide) :
import numpy
def firstNotPresent(l):
positive = numpy.fromiter(set(l), dtype=int) # dédupliquer
positive = positive[positive > 0] # ne garder que les nombres positifs
positive.sort()
top = positive.size + 1
if top == 1: # liste vide
return 1
sequence = numpy.arange(1, top)
try:
return numpy.where(sequence < positive)[0][0]
except IndexError: # aucun nombre ne manque, top est le suivant
return top
L'idée est la suivante : si vous énumérez la liste triée, dédupliquée et positive à partir de un, la première fois que l'index est inférieur à la valeur de la liste, la valeur de l'index manque dans la liste et est donc le plus petit nombre positif manquant dans la liste.
Ce code et les autres solutions que j'ai testées (celles de adrtam, Paritosh Singh et VPfB) semblent toutes être environ O(n), comme prévu. (Je pense que c'est assez évident que c'est une borne inférieure, puisque chaque élément de la liste doit être examiné pour trouver la réponse.) Édition : En y repensant, bien sûr, le grand O pour cette approche est au moins O(n log(n)), en raison du tri. C'est juste que le tri est tellement rapide en comparaison qu'il semblait linéaire dans l'ensemble.