我是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用户。
非常感谢提前。
答案 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 )