Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
Example 1:
Input: [1,3,4,2,2]
Output: 2
Example 2:
Input: [3,1,3,4,2] Output: 3
Note:
- You must not modify the array (assume the array is read only).
- You must use only constant, O(1) extra space.
- Your runtime complexity should be less than O(n2).
- There is only one duplicate number in the array, but it could be repeated more than once.
Approach #1: Using hash table
time(O(N)) space(O(n))
class Solution { public: int findDuplicate(vector<int>& nums) { int len = nums.size(); vector<int> temp(len, 0); for (int i = 0; i < len; ++i) if (++temp[nums[i]] == 2) return nums[i]; } };
Approach #2 Floyd's Tortoise and Hare (Cycle Detection)
time(O(n)) space(O(1))
class Solution { public: int findDuplicate(vector<int>& nums) { int tortoise = nums[0]; int hare = nums[0]; // Find the intersection point of the two runner. do { tortoise = nums[tortoise]; hare = nums[nums[hare]]; } while (tortoise != hare); // Find the "entrance" to the cycle int ptr1 = nums[0]; int ptr2 = tortoise; while (ptr1 != ptr2) { ptr1 = nums[ptr1]; ptr2 = nums[ptr2]; } return ptr1; } };
Runtime: 8 ms, faster than 83.02% of C++ online submissions for Find the Duplicate Number.