web-dev-qa-db-ja.com

Python N個の整数の配列Aを指定すると、Aで発生しない最小の正の整数(0より大きい)をO(n)時間の複雑さで返します

私はその問題に対する2つの解決策を書きました。最初のものは良いですが、外部ライブラリとそのO(n)* log(n)の複雑さを使用したくありません。 2番目のソリューション「最適化するにはあなたの助けが必要です」は、入力がカオスシーケンスlength = 10005(マイナス付き)の場合にエラーを出します。

解決策1:

from itertools import count, filterfalse 


def minpositive(a):
    return(next(filterfalse(set(a).__contains__, count(1))))

解決策2:

def minpositive(a):
    count = 0
    b = list(set([i for i in a if i>0]))
    if min(b, default = 0)  > 1 or  min(b, default = 0)  ==  0 :
        min_val = 1
    else:
        min_val = min([b[i-1]+1 for i, x in enumerate(b) if x - b[i - 1] >1], default=b[-1]+1)

    return min_val

注:これはコードのデモテストであり、ソリューション1は100%、ソリューション2は77%でした。
「solution2」のエラーの原因:
パフォーマンステスト->中程度のカオスシーケンスlength = 10005(マイナスを含む)で3が予想される10000
パフォーマンステスト->大規模なカオス+多くの-1、1、2、3(マイナスあり)で5が予想される10000

5
user8358337

Python)では、セット内の数値の存在のテストが高速であるため、次のようなことを試すことができます。

def minpositive(a):
    A = set(a)
    ans = 1
    while ans in A:
       ans += 1
    return ans
12
Peter de Rivaz
def solution(A):
    B = set(sorted(A))
    m = 1
    for x in B:
        if x == m:
            m+=1
    return m
1
Najeeb Jebreel

セットを使用せずに、私はこのソリューションを思いつきました:

def smallest_missing_positive_integer(A):
    A.sort()
    N = len(A)
    
    i = 0
    previous = 0
    while i < N:
        current = A[i]

        if current > 0:
            if current > previous + 1: # breaks consecutiveness
                return previous + 1
            else:
                previous = current
        
        i += 1
    
    return max(previous+1, current+1)