如何在数组中找到所有未使用和首次丢失的数字(在Python中)?

时间:2016-08-16 14:36:43

标签: python arrays dynamic

我是python的新手,我需要帮助才能找到数组中所有未使用的和第一个未使用/缺失的数字(在python 2.7.3中)?

数组长度为20,由应用程序使用。启动应用程序时,阵列为空,但是当用户开始填充它时,我需要找到所有未使用的数字和第一个未使用的数字。

将它想象成一个停车场,有20个点,编号为1到20.随着人们开始停放车辆,空间就会被填满。人们可能不一定按顺序停放汽车,两个人可能会停在1号和16号火车站,所以我需要找到所有缺失的地点和第一个未使用的停车位。

以停车场为例,帮助您了解我想传达的内容。数组将始终为整数,并保持1到20之间的值。

以下是代码应该做的事情

在启动时,myArray为空:

myarray = []

所以第一个缺失的数字应该是1(即第一个位置的Park车)

missingNumbers = [1,2,3,.......20]
firstMissingNoInMyArray = 1

当数组中的空格被填充时,数组将如下所示

myarray = [1, 5, 15]

所以首先缺少的数字和缺少的数字是:

missingNumbers = [2,3,4,6,7,8,9,10,11,12,13,14,16,17,18,19,20]. 
firstMissingNoInMyArray = 2 

我需要查看缺少的数字列表和第一个缺失的数字,任何人都可以帮助使用Python代码,我只能使用Python 2.7.3;如果你有一个Python 3的解决方案,那么写它,它可以帮助Python 3用户。

非常感谢提前。

4 个答案:

答案 0 :(得分:2)

您可以使用set s然后您可以简单地减去这些集合。 要查看第一个缺失的数字,您可以在结果集中使用min

all_nums = set(xrange(1, 21))
arr = set(xrange(5, 10))

print all_nums - arr 
print min(all_nums - arr) 
# note that sets are unordered
>>   {1, 2, 3, 4, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
     1

这个 应该在Python 2.7.3上运行,但你应该考虑升级。 Python 2.7.3已有7年历史了。

答案 1 :(得分:1)

我认为这个列表理解应该为你做的伎俩

missingNumbers = [ i  for i in range(20) if i not in myarray ]

获取第一个数字,你只需要取第一个元素

firstMissingNoInMyArray = missingNumbers[0]

答案 2 :(得分:1)

您可以使用set次操作。

limit = 20
myarray = [1, 5, 15]  # Example
missingNumbers = list(set(range(1, limit + 1)) - set(myarray))

print 'Missing numbers ->', missingNumbers
print 'First missing number ->', missingNumbers[0] # Access the first element.

示例输出:

Missing numbers -> [2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20] 
First missing number -> 2

虽然用户@ Magellan88 的解决方案非常pythonic,但设置操作已针对此类计算进行了高度优化。在下面运行一些基准测试,即使对于较小的数据集,列表理解也需要更长的时间来完成执行 - > 搜索列表 100,000件列表要减去 - > 100件。

import timeit
print timeit.timeit("list(set(range(1,100000)) - set(range(1,100)))", number=100)
print timeit.timeit("[ i  for i in range(1,100000) if i not in myarray]", number=100, setup="myarray = range(1,100)")

结果(以秒为单位):

  
      
  • 1.43372607231 - 设置操作
  •   
  • 18.2217440605 - 列表理解
  •   

设置差异是一项成本相对较低的操作,时间复杂度为 O(n) ,(复杂性 python documentation )。 python中的集合基本上是使用散列表实现的,这使得非常快速的操作( source code )。

同时,在列表理解中,有一个in操作,其平均情况为 O(n) ,此操作发生在for中循环 O(n) ,从而为我们提供 O(n 2 )的平均时间复杂度 即可。列表理解遵循二次渐近增长模式(远远低于设置操作)。

答案 3 :(得分:0)

如果您知道范围的上限,则从预先填充的列表中删除来自用户的元素并返回第一个元素。如下所示:

prepop_list = [ i for i in xrange( 1, 20+1 ) ]

def new_user( item ):
    if item in prepop_list:
        prepop_list.remove( item )
    else:
        return "Item "+ str(item) +" not found"

    return prepop_list[0]

first_e_pos = new_user( 4 ) # some new user reserved 4th position
print( first_e_pos )