[英]Is there a more efficient way to find the missing integer?
我目前正在大学学习一个名为数据结构和算法的模块。 我们的任务是编写一种算法,找到在给定序列中不出现的最小正数 integer。 我能够找到解决方案,但有没有更有效的方法?
x = [5, 6, 3, 1, 2]
def missing_integer():
for i in range(1, 100):
if i not in x:
return i
print(missing_integer())
说明包括一些示例:
给定 x = [1, 3, 6, 4, 1, 2],function 应该返回 5,
给定 x = [1, 2, 3],function 应该返回 4 和
给定 x = [−1, −3],function 应该返回 1。
你没有要求解决问题的最有效方法,只是如果有比你的方法更有效的方法。 答案是肯定的。
如果缺失的整数接近整数范围的顶部并且列表很长,则您的算法作为O(N**2)
的运行时效率 - 您的循环遍历所有可能的值,而not in
如果未找到匹配项,运算符将搜索整个列表。 (您的代码最多只能搜索100
值——我认为这只是您的错误,您想要处理任何长度的序列。)
这是一个简单的算法,它的顺序仅为O(N*log(N))
。 (请注意,存在更快的算法——我展示了这个,因为它很简单,因此很容易回答你的问题。)对序列进行排序(具有我陈述的顺序),然后从最小值开始运行它。 这种线性搜索很容易找到丢失的正整数。 该算法还有一个优点,序列可以涉及负数、非整数和重复数,代码可以轻松处理这些。 这也可以处理任意大小的序列和任意大小的数字,当然它对于更长的序列运行时间更长。 如果使用良好的排序例程,则内存使用量非常小。
我认为O(n)
算法是这样的:将长度为n + 2
(Python 中的列表)的数组记录初始化为None
,然后迭代输入。 如果元素是数组索引之一,则将记录中的元素设置为True
。 现在从索引 1 开始迭代新的列表记录。返回遇到的第一个None
。
另一种解决方案是创建一个大小为Max
值的数组,并遍历该数组并在看到该值时标记该数组的每个位置。 然后,从数组的开头开始迭代,将第一个找到的未标记位置报告为最小缺失值。 这是在O(n)
(填充数组并找到最小的未标记位置)。
此外,对于负值,您可以将所有值与Min
加以找到所有正值。 然后,应用上述方法。 这种方法的空间复杂度是\\Theta(n)
。
要了解更多信息,请参阅有关实现的这篇文章,并详细了解此方法。
算法中的缓慢步骤是那一行:
if i not in x:
该步骤需要线性时间,这使得整个算法O(N*N)
。 如果首先将列表转换为集合,则查找速度要快得多:
def missing_integer():
sx = set(x)
for i in range(1, 100):
if i not in sx:
return i
在集合中查找很快,实际上它需要恒定的时间,并且该算法现在以线性时间 O(N) 运行。
可以用一点数学在 O(n) 时间内完成。 初始化一个 minimum_value 和 maximum_value ,然后 sum_value 名称然后通过数字循环一次以找到最小值和最大值以及所有数字的总和(mn, mx, sm)
。
现在整数之和0..n = n*(n-1)/2 = s(n)
因此: missing_number = (s(mx) - s(mn)) - sm
只需遍历一次数字即可完成所有操作!
我使用列表理解的答案:
def solution(A):
max_val = max(A);
min_val = min(A);
if max_val<0: val = 1;
elif max_val > 0:
li = [];
[li.append(X) for X in range(min_val,max_val) if X not in A];
if len(li)>0:
if min(li)<0: val = 1;
else: val = min(li);
if len(li)==0: val=max_val+1;
return val;
L = [-1, -3];
res = solution(L);
print(res);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.