forked from MTrajK/coding-problems
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfind_first_missing_positive.py
More file actions
129 lines (100 loc) · 3.03 KB
/
find_first_missing_positive.py
File metadata and controls
129 lines (100 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
'''
Find first missing positive integer (>0)
Given an array of integers, find the first missing positive integer in linear time and constant space.
In other words, find the lowest positive integer that does not exist in the array.
The array can contain duplicates and negative numbers as well.
Note: you can modify the input array in-place.
Input: [3, 4, -1, 1]
Output: 2
Input: [1, 2, 0]
Output: 3
=========================================
Move all values to their positions (val position = val - 1), in the end find the first
position which doesn't have the needed value.
Time Complexity: O(N) , maybe nested loops look like O(N^2) but that not true
Space Complexity: O(1)
Play with indicies and mark them (make it negative),
a marked index means that the number equals to that index exist in the array.
Time Complexity: O(N)
Space Complexity: O(1)
'''
##############
# Solution 1 #
##############
def find_first_missing_1(a):
n = len(a)
for i in range(n):
while (a[i] > 0) and (a[i] <= n):
swap = a[i] - 1
if a[i] == a[swap]:
break
# swap elements
a[i], a[swap] = a[swap], a[i]
for i in range(n):
if a[i] - 1 != i:
return i + 1
return n + 1
##############
# Solution 2 #
##############
def find_first_missing_2(a):
n = len(a)
# eliminate all zeros and all negative numbers
for i in range(n):
if a[i] <= 0:
a[i] = n + 1 # those values won't be used later
# find all numbers in the range and mark all numbers at those positions as negative numbers
for i in range(n):
idx = abs(a[i]) - 1
if idx >= n:
continue
# mark the element as found
a[idx] = -abs(a[idx])
# find the first non-negative position
for i in range(n):
if a[i] > 0:
return i + 1
return n + 1
###########
# Testing #
###########
# Test 1
# Correct result => 1
test = [-1, 2, 3]
print(find_first_missing_1(list(test))) # make a copy, the list will be changed inside the function
print(find_first_missing_2(list(test)))
# Test 2
# Correct result => 2
test = [3, 4, -1, 1]
print(find_first_missing_1(list(test)))
print(find_first_missing_2(list(test)))
# Test 3
# Correct result => 3
test = [1, 2, 0]
print(find_first_missing_1(list(test)))
print(find_first_missing_2(list(test)))
# Test 4
# Correct result => 4
test = [1, 2, 3]
print(find_first_missing_1(list(test)))
print(find_first_missing_2(list(test)))
# Test 5
# Correct result => 1
test = [-4, -1, -3, -1]
print(find_first_missing_1(list(test)))
print(find_first_missing_2(list(test)))
# Test 6
# Correct result => 3
test = [2, 1, 2, -1, 0, 20]
print(find_first_missing_1(list(test)))
print(find_first_missing_2(list(test)))
# Test 7
# Correct result => 3
test = [1, 2, 5, 5, 1, 2]
print(find_first_missing_1(list(test)))
print(find_first_missing_2(list(test)))
# Test 8
# Correct result => 4
test = [1, 2, 3, 5, 1, 2, 3, 3]
print(find_first_missing_1(list(test)))
print(find_first_missing_2(list(test)))