📅  最后修改于: 2023-12-03 15:26:36.107000             🧑  作者: Mango
给定一个正整数集合S,S中所有数字均为非负整数。现在你需要找到最小的正整数X,使得无论你选取集合S中的任意数量的数字,若干个它们的和等于X,总是可以找到一种方案使得被选取的数字中不含有数字X。
为了方便,我们将集合S中的所有数字按升序排序。设当前已经找到的最小正整数为X,已经处理完的数的和为sum,正在处理的数的下标为i。那么,有如下的推论:
理由如下:
首先考虑第一种情况。如果S[i]小于等于sum+1,我们可以向S[i]添加一个S[j],使得S[j]=S[i]+S[j],使得S[j]的范围扩大到S[1:i]。如果S[j]小于等于sum+1,那么X 就被更新为 X+S[j]。因为sum < X <= sum+S[j],所以X 是最小的正整数(sum+S[k],k < j,显然小于X,sum+S[k],k >= j 显然大于X)。
如果S[j]大于sum+1,那么X = sum+1,原因如下:假设X!=sum+1,那么sum+1必定可以用集合S中的若干个数表示。由于X是最小的不能用S中的数表示的正整数,所以sum+1可以用S中的数表示。这样,我们可以将大于S[j]的元素,从S[j]的集合中除去,并将S[j]并入S[1:j-1]集合中,然后进行下一次遍历。
def find_minimun_positive(S):
X = 1
for i in range(len(S)):
if S[i] <= X:
X += S[i]
else:
break
return X
在调用完这个函数之后,程序会首先排序,排序的复杂度为O(nlgn),接下来遍历一遍S,时间复杂度为O(n),加起来就是O(nlgn+n),即最坏时间复杂度为O(nlgn)。
空间复杂度为O(1),因为无论集合S中有多少元素,X都只需要一个整数的空间存储。