master
 1<<-DOC
 2Note: Write a solution with O(n) time complexity and O(1) additional space complexity, 
 3since this is what you would be asked to do during a real interview.
 4
 5Given an array a that contains only numbers in the range from 1 to a.length,
 6find the first duplicate number for which the second occurrence has the minimal index.
 7In other words, if there are more than 1 duplicated numbers, 
 8return the number for which the second occurrence has a smaller index than the second occurrence of the other number does. 
 9If there are no such elements, return -1.
10
11Example
12
13For a = [2, 3, 3, 1, 5, 2], the output should be
14firstDuplicate(a) = 3.
15
16There are 2 duplicates: numbers 2 and 3. The second occurrence of 3 has a smaller index than than second occurrence of 2 does, 
17so the answer is 3.
18
19For a = [2, 4, 3, 5, 1], the output should be
20firstDuplicate(a) = -1.
21
22Input/Output
23
24[time limit] 4000ms (rb)
25[input] array.integer a
26
27Guaranteed constraints:
281  a.length  105,
291  a[i]  a.length.
30
31[output] integer
32
33The element in a that occurs in the array more than once and has the minimal index for its second occurrence. 
34If there are no such elements, return -1.
35DOC
36
37describe "first_duplicate" do
38  def first_duplicate(items)
39    head, tail = 0, 1
40    min = -1
41    n = items.size
42
43    until head == (n - 1) || head == min
44      puts [items[head], items[tail]].inspect
45      if items[head] == items[tail]
46        min = min < 0 ?  tail + 1 : [min, tail + 1].min
47        puts ['match', items[head], items[tail], min].inspect
48        head += 1
49        tail = head + 1
50        break if tail == head
51      else
52        tail += 1
53        break if min >= 0 && tail > min
54        if tail == n
55          head += 1
56          tail = head + 1
57        end
58      end
59    end
60    min > 0 ? items[min - 1] : min
61  end
62
63  def first_duplicate(items)
64    hash = {}
65    items.each do |item|
66      return item if hash[item]
67      hash[item] = true
68    end
69    -1
70  end
71
72  [
73    { a: [2, 3, 3, 1, 5, 2], x: 3 },
74    { a: [2, 4, 3, 5, 1], x: -1 },
75    { a: [1], x: -1 },
76    { a: [2, 2], x: 2 },
77    { a: [2, 1], x: -1 },
78    { a: [2, 1, 3], x: -1 },
79    { a: [2, 3, 3], x: 3 },
80    { a: [3, 3, 3], x: 3 },
81    { a: [8, 4, 6, 2, 6, 4, 7, 9, 5, 8], x: 6 },
82    { a: [10, 6, 8, 4, 9, 1, 7, 2, 5, 3], x: -1 },
83    { a: [1, 2, 3, 4, 5, 6, 7, 8, 9, 9], x: 9 },
84  ].each do |x|
85    it do
86      expect(first_duplicate(x[:a])).to eql(x[:x])
87    end
88  end
89end