1. Hash Set / Sorting
Intuition
Use a Hash Set to track seen numbers, or sort the array and look for adjacent duplicates.
Algorithm
- 1. Initialize a hash set seen.
- 2. Iterate through each num in nums.
- 3. If num is already in seen, return num.
- 4. Otherwise, insert num into seen.
- 5. Uses O(N) space or modifies the array in O(N log N) time.
Brute Force Nested Pairwise Comparison Trace
2 of 2 questions left todayInspect i=0: Value 1 has no duplicate
Inspect i=0: Value 1 has no duplicate. Advance i.
#include <iostream>#include <vector>#include <string>#include <algorithm>#include <unordered_map>#include <unordered_set>#include <queue>#include <stack>#include <numeric>#include <climits> using namespace std; class Solution {public: int findDuplicate(vector<int>& nums) { unordered_set<int> seen; for (int num : nums) { if (seen.count(num)) return num; seen.insert(num); } return -1; }}; int main() { Solution sol; vector<int> nums = {1, 3, 4, 2, 2}; cout << "Duplicate Number: " << sol.findDuplicate(nums) << endl; return 0;}Time & Space Complexity
- Time complexity:
O(N)— A single linear pass with O(1) set lookups takes O(N) time. - Space complexity:
O(N)— Hash Set stores up to N distinct elements, requiring O(N) space.
Why Brute Force Doesn't Scale:
Since nums[i] is between 1 and n, 0 is never in the range. This ensures index 0 is always outside the cycle and serves as a valid list head. When slow moves by 1 step (slow = nums[slow]) and fast moves by 2 steps (fast = nums[nums[fast]]), they must meet inside the loop after at most N steps. The mathematical distance from the start to the cycle entrance equals the distance from the intersection point to the cycle entrance.
For N = 100,000: Binary Search performs ~1,700,000 checks. Floyd's cycle detection finishes in ~150,000 operations.