[英]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.