问题
I'm new to python and I need help in trying to find all unused and the first unused/missing number in an array (in python 2.7.3)?
The array is of length 20 and is used by an application. When the application is launched, the array is empty, but as users begin to populate it, I need to find all unused numbers and first unused number.
Think of it as a car-park with 20 spots numbered 1 to 20. As people begin to park their cars, the spaces get filled. People may not necessarily park cars in a sequence, two people may park in spots 1 and 16, so i need to find all the missing spots and the first unused parking spot.
Parking cars is given as an example to help you understand what I'm trying to convey. Array will always be integer, and will hold values from 1 to 20.
Below is what the code should do
On Launch, myArray is empty:
myarray = []
So the first missing number should be 1 (i.e. Park car in first spot)
missingNumbers = [1,2,3,.......20]
firstMissingNoInMyArray = 1
As spaces in the array are filled, the array will look like this
myarray = [1, 5, 15]
So first missing number and missing numbers are:
missingNumbers = [2,3,4,6,7,8,9,10,11,12,13,14,16,17,18,19,20].
firstMissingNoInMyArray = 2
I need to see both missing numbers list and the first missing number, can anyone help with Python code, I'm restricted to using Python 2.7.3; if you have a solution in Python 3, do write it, it may help Python 3 users.
Many thanks in advance.
回答1:
You can use sets then you can simply subtract the sets.
In order to see the first missing number you can take the min in the resulting set:
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
This should work on Python 2.7.3, but you should consider upgrading anyway. Python 2.7.3 is 7 years old.
回答2:
I think this listcomprehension should do the trick for you
missingNumbers = [ i for i in range(20) if i not in myarray ]
to get the first number you only need to take the first element
firstMissingNoInMyArray = missingNumbers[0]
回答3:
You could use set operations.
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.
Sample Output:
Missing numbers -> [2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20]
First missing number -> 2
Although user @Magellan88's solution is quite pythonic, set operations are highly optimized for this class of calculations. Running some bench marks below, the list comprehension takes significantly longer to finish execution even for smaller data sets -> Search list: 100,000 items, list to subtract -> 100 items.
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)")
Results (in seconds):
- 1.43372607231 - Set operations.
- 18.2217440605 - List comprehension.
Set difference is a relatively low costing operation with a time complexity of O(n), (python documentation on complexities). Sets in python are essentially implemented using a hash-table giving way to very fast operations (source code).
Meanwhile, in the list comprehension, there is an in operation which has an average case of O(n), this operation occurs within a for loop O(n), thus giving us an average time complexity of O(n2). The list comprehension follows a quadratic asymptotic growth pattern (far slower than the set operation).
回答4:
If you know the upper limit of the range, then remove element, that came from user, from pre-populated list and return the first element. Like below:
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 )
来源:https://stackoverflow.com/questions/38977776/how-to-find-all-unused-and-first-missing-number-in-an-array-in-python