↓Skip to main content
  1. LeetCode/

LeetCode 287: Find the Duplicate Number

·2 mins· ·
LeetCode Medium Array Two-Pointers Binary-Search Bit-Manipulation
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2022-10-29

  • Submissions: Wrong Answer → Accepted ×3

Approach
#

Values are in 1..n with n + 1 of them; treat i -> nums[i] as “node points to next”. Two indices pointing at the same value make that value the cycle entry (Linked List Template 3, LC 142):

  1. Fast and slow pointers start at 0 and meet inside the cycle.
  2. Send one back to 0 and step both one at a time; they meet at the entry, the duplicate.

My Attempts
#

Attempt 1 used sum(nums) - sum(set(nums)), which works only when the duplicate appears exactly twice: [2, 2, 2, 2] should be 2; it returned 6.

Solution
#

class Solution:
    def findDuplicate(self, nums: List[int]) -> int:
        slow = fast = 0
        while True:
            slow, fast = nums[slow], nums[nums[fast]]
            if slow == fast:
                break
        slow = 0
        while slow != fast:
            slow, fast = nums[slow], nums[fast]
        return slow

Complexity
#

Time O(n), space O(1).

Mistakes to Avoid
#

  • The duplicate may appear more than twice; sum(nums) - sum(set(nums)) works only for exactly two.

Interview Explanation
#

Pointing each index at nums[i] forms a list with a cycle whose entry is the duplicate. With Floyd’s algorithm, fast and slow pointers meet, then one restarts and both step together until they meet at the answer. Time O(n), space O(1).

Related

LeetCode 167: Two Sum II - Input Array Is Sorted
·2 mins
LeetCode Medium Array Two-Pointers Binary-Search
LeetCode 167 note: sorted, so move two pointers inward, shifting right when the sum is too large and left when too small; indices are 1-based
LeetCode 153: Find Minimum in Rotated Sorted Array
·2 mins
LeetCode Medium Array Binary-Search
LeetCode 153 note: compare mid with the right end: nums[mid] > nums[r] puts the minimum to the right, otherwise mid may be it, so r = mid
LeetCode 875: Koko Eating Bananas
·2 mins
LeetCode Medium Array Binary-Search
LeetCode 875 note: binary search the speed for the smallest k with total hours <= h, continuing left even when the hours equal h
LeetCode 75: Sort Colors
·2 mins
LeetCode Medium Array Two-Pointers Sorting Quicksort
LeetCode 75 note: the Dutch flag, with 0s left of low and 2s right of high; after swapping a 2 to high, do not advance, since the swapped-in value is unchecked
LeetCode 78: Subsets
·1 min
LeetCode Medium Array Backtracking Bit-Manipulation
LeetCode 78 note: each element is either taken or not; iteratively, each new number copies every existing subset with the number appended
LeetCode 80: Remove Duplicates from Sorted Array II
·1 min
LeetCode Medium Array Two-Pointers
LeetCode 80 note: keep each value at most twice by comparing with nums[k - 2], two slots back from the write position