Find the Duplicate Number
Problem
Section titled “Problem”Given an array of integers nums containing n + 1 integers where each integer is in the range [1, n] inclusive.
There is only one repeated number in nums, return this repeated number.
You must solve the problem without modifying the array nums and uses only constant extra space.
Solution approach
Section titled “Solution approach”Intuition
Section titled “Intuition”Treat the array as a function: from index i we move to index nums[i]. All values lie in [1, n], so starting at index 0 we can follow this forever. Since two different indices point to the duplicate value, that value has two incoming arrows, and it is exactly the entrance of the cycle we eventually fall into. Floyd’s tortoise-and-hare method finds a cycle entrance in time without extra memory and without modifying the array.
Algorithm
Section titled “Algorithm”- Start from index
0:slow = nums[0](one step) andfast = nums[nums[0]](two steps). - Move
slowone step andfasttwo steps until they meet inside the cycle. - Reset
fast = 0. Now move both one step at a time; the point where they meet is the cycle entrance. - Return
slow, the duplicate value. Ifnums.size()is1or less, return-1.
Complexity
Section titled “Complexity”- Time: — both phases take at most a linear number of steps.
- Space: — only two pointers.
Edge cases
Section titled “Edge cases”- Duplicate appearing many times (e.g.
[2, 2, 2, 2]): it is still the only value with several incoming arrows, so it is still the cycle entrance.
class Solution { public: int findDuplicate(vector<int>& nums) { if (nums.size() > 1) { int slow = nums[0]; int fast = nums[nums[0]]; while (slow != fast) { slow = nums[slow]; fast = nums[nums[fast]]; }
fast = 0; while (fast != slow) { fast = nums[fast]; slow = nums[slow]; } return slow; } return -1; }};Give it a try first
Attempt the problem on LeetCode — the code will still be here.