Commit 33afc78

mo <mokha@cisco.com>
2017-06-23 03:11:54
find min duplicate.
1 parent d7e0c7f
Changed files (1)
spec/first_duplicate_spec.rb
@@ -0,0 +1,75 @@
+<<-DOC
+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 (rb)
+[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.
+DOC
+
+describe "first_duplicate" do
+  def first_duplicate(items)
+    head, tail = 0, items.size - 1
+    min = -1
+
+    until head == (items.size - 1)
+      #puts [items[head], items[tail]].inspect
+      if items[head] == items[tail]
+        new_min = tail + 1
+        min = min < 0 ?  new_min : [min, new_min].min
+        head += 1
+        break if tail == head
+      else
+        tail -= 1
+        if tail == head
+          tail = items.size - 1
+          head += 1
+        end
+      end
+    end
+    min
+  end
+
+  [
+    { a: [2, 3, 3, 1, 5, 2], x: 3 },
+    { a: [2, 4, 3, 5, 1], x: -1 },
+    { a: [1], x: -1 },
+    { a: [2, 2], x: 2 },
+    { a: [2, 1], x: -1 },
+    { a: [2, 1, 3], x: -1 },
+    { a: [2, 3, 3], x: 3 },
+    { a: [3, 3, 3], x: 3 },
+    { a: [8, 4, 6, 2, 6, 4, 7, 9, 5, 8], x: 6 },
+    { a: [10, 6, 8, 4, 9, 1, 7, 2, 5, 3], x: -1 },
+  ].each do |x|
+    it do
+      expect(first_duplicate(x[:a])).to eql(x[:x])
+    end
+  end
+end