forked from learning-zone/python-basics
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfirst_duplicate.py
115 lines (74 loc) · 2.51 KB
/
first_duplicate.py
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
"""
Note: Write a solution with O(n) time complexity and O(1) additional space complexity, since this is what you would be asked to do during a real interview.
Given an array a that contains only numbers in the range from 1 to a.length, find the first duplicate number for which the second occurrence has the minimal index. In other words, if there are more than 1 duplicated numbers, return the number for which the second occurrence has a smaller index than the second occurrence of the other number does. If there are no such elements, return -1.
Example
For a = [2, 3, 3, 1, 5, 2], the output should be
firstDuplicate(a) = 3.
There are 2 duplicates: numbers 2 and 3. The second occurrence of 3 has a smaller index than than second occurrence of 2 does, so the answer is 3.
For a = [2, 4, 3, 5, 1], the output should be
firstDuplicate(a) = -1.
Input/Output
[time limit] 4000ms (py)
[input] array.integer a
Guaranteed constraints:
1 <= a.length <= 105,
1 <= a[i] <= a.length.
[output] integer
The element in a that occurs in the array more than once and has the minimal index for its second occurrence. If there are no such elements, return -1.
"""
def first_duplicate(a):
"""
>>> first_duplicate([8, 4, 6, 2, 6, 4, 7, 9, 5, 8])
6
>>> first_duplicate([2, 3, 3, 1, 5, 2])
3
>>> first_duplicate([1])
-1
>>> first_duplicate([2, 1])
-1
>>> first_duplicate([2, 2])
2
>>> first_duplicate([2, 4, 3, 5, 1])
-1
"""
# time: O(n^2)
# space: O(n)
lowest_index = len(a)
for i in range(len(a)):
num = a[i]
if num in a[i+1:]:
index = a[i+1:].index(num) + i + 1
if index < lowest_index:
lowest_index = index
if lowest_index < len(a):
return a[lowest_index]
return -1
def first_duplicate_optimized(arr):
"""
>>> first_duplicate_optimized([8, 4, 6, 2, 6, 4, 7, 1, 5, 8])
6
>>> first_duplicate_optimized([2, 3, 3, 1, 5, 2])
3
>>> first_duplicate_optimized([1])
-1
>>> first_duplicate_optimized([2, 1])
-1
>>> first_duplicate_optimized([2, 2])
2
>>> first_duplicate([2, 4, 3, 5, 1])
-1
"""
# time: O(n)
# space: O(1)
for i in range(len(arr)):
value = arr[abs(arr[i])-1]
if value >= 0:
arr[abs(arr[i])-1] = -value
else:
return abs(arr[i])
return -1
if __name__ == "__main__":
import doctest
results = doctest.testmod()
if not results.failed:
print "All tests passed!"