简体   繁体   English

Python 给定一个N个整数的数组A,在O(n)时间复杂度内返回A中没有出现的最小正数integer(大于0)

[英]Python given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A in O(n) time complexity

For example:例如:

input: A = [ 6 4 3 -5 0 2 -7 1 ]输入:A = [ 6 4 3 -5 0 2 -7 1 ]

output: 5 output:5

Since 5 is the smallest positive integer that does not occur in the array.由于 5 是数组中未出现的最小正数 integer。


I have written two solutions to that problem.我已经为该问题编写了两个解决方案。 The first one is good but I don't want to use any external libraries + its O(n)*log(n) complexity.第一个很好,但我不想使用任何外部库 + 它的 O(n)*log(n) 复杂性。 The second solution "In which I need your help to optimize it" gives an error when the input is chaotic sequences length=10005 (with minus).当输入是混沌序列 length=10005(带负号)时,第二个解决方案“我需要你的帮助来优化它”会出错。

Solution 1:解决方案 1:

from itertools import count, filterfalse 


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

Solution 2:解决方案 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

Note: This was a demo test in codility, solution 1 got 100% and solution 2 got 77 %.注意:这是 codility 的演示测试,解决方案 1 获得 100%,解决方案 2 获得 77%。
Error in "solution2" was due to: “solution2”中的错误是由于:
Performance tests -> medium chaotic sequences length=10005 (with minus) got 3 expected 10000性能测试 -> 中等混沌序列长度=10005(带负号)得到 3 个预期的 10000
Performance tests -> large chaotic + many -1, 1, 2, 3 (with minus) got 5 expected 10000性能测试 -> large chaotic + many -1, 1, 2, 3 (with minus) got 5 expected 10000

Testing for the presence of a number in a set is fast in Python so you could try something like this:在 Python 中测试集合中是否存在数字很快,因此您可以尝试以下操作:

def minpositive(a):
    A = set(a)
    ans = 1
    while ans in A:
       ans += 1
    return ans

Fast for large arrays.快速用于大型阵列。

def minpositive(arr):
    if 1 not in arr: # protection from error if ( max(arr) < 0 )
        return 1
    else:
        maxArr = max(arr) # find max element in 'arr'
        c1 = set(range(2, maxArr+2)) # create array from 2 to max
        c2 = c1 - set(arr) # find all positive elements outside the array
        return min(c2)

I have written two solutions to that problem.我已经写了两个解决方案来解决这个问题。 The first one is good but I don't want to use any external libraries + its O(n)*log(n) complexity.第一个很好,但我不想使用任何外部库 + 它的 O(n)*log(n) 复杂度。 The second solution "In which I need your help to optimize it" gives an error when the input is chaotic sequences length=10005 (with minus).当输入是混乱序列长度=10005(带减号)时,第二个解决方案“我需要你的帮助来优化它”会出错。

Solution 1:解决方案1:

from itertools import count, filterfalse 


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

Solution 2:解决方案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

Note: This was a demo test in codility, solution 1 got 100% and solution 2 got 77 %.注意:这是一个 codility 的演示测试,解决方案 1 为 100%,解决方案 2 为 77%。
Error in "solution2" was due to: “solution2”中的错误是由于:
Performance tests -> medium chaotic sequences length=10005 (with minus) got 3 expected 10000性能测试 -> 中等混乱序列长度 = 10005(带减号)得到 3 预期 10000
Performance tests -> large chaotic + many -1, 1, 2, 3 (with minus) got 5 expected 10000性能测试 -> 大混乱 + 许多 -1, 1, 2, 3(带减号)得到 5 预期 10000

def minpositive(A):
    """Given an list A of N integers, 
    returns the smallest positive integer (greater than 0) 
    that does not occur in A in O(n) time complexity

        Args:
            A: list of integers
        Returns:
            integer: smallest positive integer

        e.g:
            A = [1,2,3]
            smallest_positive_int = 4
    """
    len_nrs_list = len(A)
    N = set(range(1, len_nrs_list+2))
    
    return min(N-set(A)) #gets the min value using the N integers
    

This solution passes the performance test with a score of 100%该解决方案以 100% 的分数通过了性能测试

def solution(A):
    n = sorted(i for i in set(A) if i > 0)  # Remove duplicates and negative numbers
    if not n:
        return 1
    ln = len(n)

    for i in range(1, ln + 1):
        if i != n[i - 1]:
            return i

    return ln + 1

I have an easy solution.我有一个简单的解决方案。 No need to sort.无需排序。

def solution(A):
    s = set(A)
    m = max(A) + 2
    for N in range(1, m):
        if N not in s:
            return N
    return 1

Note: It is 100% total score (Correctness & Performance)注意:这是 100% 总分(正确性和表现)

Without using set I come up with this solution: 不使用set我想出了这个解决方案:

 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) 

def solution(A):
    B = set(sorted(A))
    m = 1
    for x in B:
        if x == m:
            m+=1
    return m

Continuing on from Niroj Shrestha and najeeb-jebreel, added an initial portion to avoid iteration in case of a complete set.从 Niroj Shrestha 和 najeeb-jebreel 继续,添加了一个初始部分以避免在完整集的情况下进行迭代。 Especially important if the array is very large.如果阵列非常大,则尤其重要。

def smallest_positive_int(A):
  sorted_A = sorted(A)
  last_in_sorted_A = sorted_A[-1]
  #check if straight continuous list
  if len(sorted_A) == last_in_sorted_A:
    return last_in_sorted_A + 1
  else:
    #incomplete list, iterate to find the smallest missing number
    sol=1
    for x in sorted_A:
        if x == sol:
          sol += 1
        else:
          break
    return sol

A = [1,2,7,4,5,6]
print(smallest_positive_int(A))

This question doesn't really need another answer, but there is a solution that has not been proposed yet, that I believe to be faster than what's been presented so far.这个问题真的不需要另一个答案,但是有一个尚未提出的解决方案,我相信它比迄今为止提出的要快。

As others have pointed out, we know the answer lies in the range [1, len(A)+1] , inclusively.正如其他人指出的那样,我们知道答案在[1, len(A)+1]范围内,包括在内。 We can turn that into a set and take the minimum element in the set difference with A. That's a good O(N) solution since set operations are O(1).我们可以把它变成一个集合,并取集合中与 A 差的最小元素。这是一个很好的 O(N) 解决方案,因为集合操作是 O(1)。

However, we don't need to use a Python set to store [1, len(A)+1] , because we're starting with a dense set.但是,我们不需要使用 Python 集来存储[1, len(A)+1] ,因为我们从密集集开始。 We can use an array instead, which will replace set hashing by list indexing and give us another O(N) solution with a lower constant.我们可以使用数组代替,它将通过列表索引替换集合散列,并为我们提供另一个具有较低常数的 O(N) 解决方案。

def minpositive(a):
    # the "set" of possible answer - values_found[i-1] will tell us whether i is in a
    values_found = [False] * (len(a)+1)
    # note any values in a in the range [1, len(a)+1] as found
    for i in a:
        if i > 0 and i <= len(a)+1:
            values_found[i-1] = True
    # extract the smallest value not found
    for i, found in enumerate(values_found):
        if not found:
            return i+1

We know the final for loop always finds a value that was not marked, because it has one more element than a , so at least one of its cells was not set to True .我们知道最终的 for 循环总是找到一个未标记的值,因为它比a多一个元素,所以至少它的一个单元格没有设置为True

def 解决方案(A): len_nrs_list = len(A) N = set(range(1, len_nrs_list+2))

return min(N-set(A))
def check_min(a):
    x= max(a)
    if x-1 in a:
        return x+1
    elif x <= 0:
        return 1
    else:
        return x-1

Correct me if i'm wrong but this works for me.如果我错了,请纠正我,但这对我有用。

def solution(A):
clone = 1
A.sort()
for itr in range(max(A) + 2):
    if itr not in A and itr >= 1:
        clone = itr
        break
return clone

print(solution([2,1,4,7]))

#returns 3

I have an easy solution.我有一个简单的解决方案。 No need to sort.无需排序。

def solution(A):
    s = set(A)
    for N in range(1, 100002):
        if N not in s:
            return N

Note: It is 100% total score (Correctness & Performance)注意:这是 100% 总分(正确性和表现)

def solution(A):
    n = 1
    for i in A:
        if n in A:
            n = n+1 
        else:
            return n
    return n
def not_in_A(a):
    a=sorted(a)
    if max(a)<1:
        return(1)
    for i in range(0,len(a)-1):
        if a[i+1]-a[i]>1:
            out=a[i]+1
            if out==0 or out<1:
                continue
            return(out)
            
    return(max(a)+1)

mark and then find the first one that didn't find标记然后找到第一个没找到的

nums = [ 6, 4, 3, -5, 0, 2, -7, 1 ]
def check_min(nums):
    marks = [-1] * len(nums)
    for idx, num in enumerate(nums):
        if num >= 0:
            marks[num] = idx
    for idx, mark in enumerate(marks):
        if mark == -1:
            return idx
    return idx + 1

I just modified the answer by @najeeb-jebreel and now the function gives an optimal solution.我刚刚修改了@najeeb-jebreel 的答案,现在该函数给出了一个最佳解决方案。

def solution(A):
    sorted_set = set(sorted(A))
    sol = 1
    for x in sorted_set:
        if x == sol:
            sol += 1
        else:
            break
    return sol

I reduced the length of set before comparing我在比较之前减少了集合的长度

a=[1,222,3,4,24,5,6,7,8,9,10,15,2,3,3,11,-1]
#a=[1,2,3,6,3]
def sol(a_array):
    a_set=set()
    b_set=set()
    cnt=1
    for i in a_array:

        #In order to get the greater performance
        #Checking if element is greater than length+1 
        #then it can't be output( our result in solution)
        
        if i<=len(a) and i >=1:
            
            a_set.add(i) # Adding array element in set 
            b_set.add(cnt) # Adding iterator in set
            cnt=cnt+1
    b_set=b_set.difference(a_set)
    if((len(b_set)) > 1): 
        return(min(b_set))
    else:
        return max(a_set)+1

sol(a)  
def solution(A):
    nw_A = sorted(set(A))
    if all(i < 0 for i in nw_A):
        return 1
    else:
        ans = 1
        while ans in nw_A:
            ans += 1
            if ans not in nw_A:
                return ans

For better performance if there is a possibility to import numpy package.如果有可能导入 numpy 包,以获得更好的性能。

def solution(A):
    import numpy as np
    nw_A = np.unique(np.array(A))
    if np.all((nw_A < 0)):
        return 1
    else:
        ans = 1
        while ans in nw_A:
            ans += 1
            if ans not in nw_A:
                return ans
def solution(A):
# write your code in Python 3.6
min_num = float("inf")
set_A = set(A)
# finding the smallest number
for num in set_A:
    if num < min_num:
        min_num = num
# print(min_num)

#if negative make positive 
if min_num < 0 or min_num == 0:
    min_num = 1
# print(min_num)

# if in set add 1 until not 
while min_num in set_A:  
    min_num += 1
return min_num

Not sure why this is not 100% in correctness.不知道为什么这不是 100% 的正确性。 It is 100% performance这是100%的性能

def solution(A):
    arr = set(A)
    N = set(range(1, 100001))
    while N in arr:
       N += 1
    return min(N - arr)

solution([1, 2, 6, 4])
#returns 3

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 给定一个包含 N 个整数的数组 A,返回在 O(n) 时间复杂度内不会出现在 A 中的最小正 integer(大于 0)(Python Sol) - Given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A in O(n) time complexity (Python Sol) 取正整数n并返回小于n的所有正整数的平方和的Python函数 - Python function that takes a positive integer n and returns the sum of the squares of all the positive integers smaller than n 如何使用包含负整数的数组在 O(n) 时间复杂度中用 python 解决两个求和问题 - how to solve two sum problem with python in O(n) time complexity with an array that include negative integers Python-时间复杂度O(N ** 2) - Python - time complexity O(N**2) 接受一个正的 integer n 作为输入,并找到打印最小的 integer 可以被范围 [1, n] 内的所有整数整除 - Accept a positive integer n as input and find the print the smallest integer that is divisible by all the integers in the range [1, n] O(N)简单Python函数的时间复杂度 - O(N) Time complexity for simple Python function 给定一个非负的 integer N,返回类似于 Python 中 N 的非负整数的个数 - Given a non-negative integer N, returns the number of non-negative integers similar to N in Python 在 Python 中找到大于或等于 n 的最小 2 次方 - Find the smallest power of 2 greater than or equal to n in Python python O(n log n)中算法的时间复杂度 - Time complexity of an algorithm in python O(n log n) 为什么heappop时间复杂度在python中是O(logn)(不是O(n))? - Why heappop time complexity is O(logn) (not O(n)) in python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM