我目前正在大学里学习一个称为数据结构和算法的模块。我们的任务是编写一种算法,该算法查找在给定序列中不出现的最小正整数。我能够找到解决方案,但是有没有更有效的方法?
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],该函数应返回5,
给定x = [1,2,3],该函数应返回4和
给定x = [-1,-3],该函数应返回1。
答案 0 :(得分:2)
您并没有寻求解决问题的最有效方法,即使有比您更有效的方法。答案是是。
如果丢失的整数接近整数范围的顶部,并且列表很长,则您的算法的运行时效率为O(N**2)
-您的循环遍历了所有可能的值,而{ {1}}运算符会在整个列表中进行搜索(如果找不到匹配项)。 (您的代码最多只能搜索值not in
,因为我认为这只是您的错误,您想处理任何长度的序列。)
这是一个简单的算法,仅排序100
。 (请注意,存在更快的算法-因为它很简单,所以我将其展示出来,因此很容易回答您的问题。)对序列进行排序(按我说的顺序排序),然后从最小值开始进行遍历。此线性搜索将轻松找到丢失的正整数。该算法还具有以下优点:序列可以包含负数,非整数和重复数,并且代码可以轻松处理这些数。这也可以处理任何大小的序列,并且可以处理任何大小的数字,尽管对于更长的序列,当然它会运行更长的时间。如果使用良好的排序例程,则内存使用量会很小。
答案 1 :(得分:1)
我认为O(n)
算法是这样的:将长度为n + 2
(在Python中列出)的数组记录初始化为None
,然后遍历输入。如果元素是数组索引之一,则将记录中的元素设置为True
。现在遍历从索引1开始的新列表记录。返回遇到的第一个None
。
答案 2 :(得分:0)
另一种解决方案是创建一个大小为Max
的数组,遍历该数组并在看到该值时标记该数组的每个位置。然后,从数组的开头进行迭代,并将第一个发现的未标记位置报告为最小的缺失值。这是在O(n)
中完成的(填充数组并找到最小的未标记位置)。
此外,对于负值,您可以将所有值与Min
值相加,以找到所有正值。然后,应用上述方法。
此方法的空间复杂度为\Theta(n)
。
要了解更多信息,请参见this post有关实现,并仔细检查此方法。
答案 3 :(得分:0)
算法中最慢的一步是:
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)运行。
答案 4 :(得分:-1)
可以在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
所有这些操作仅需遍历数字一次!