Find All Duplicates in an Array
Same sign-flip trick — if `nums[|v| - 1]` is already negative, `|v|` is a duplicate.
2 min read
array in-place-hash
Problem#
nums of length n has values in [1, n], each appearing once or twice. Return all values that appear twice. Use O(1) extra space.
Examples#
[4,3,2,7,8,2,3,1]→[2,3].[1,1,2]→[1].
Constraints#
1 <= n <= 10^5.
Approach#
For each v, look at nums[|v| - 1]. If positive, negate it (first sighting). If already negative, |v| is a duplicate.
Solution#
class Solution {public: vector<int> findDuplicates(vector<int>& nums) { vector<int> ans; for (int v : nums) { int i = abs(v) - 1; if (nums[i] < 0) ans.push_back(i + 1); else nums[i] = -nums[i]; } return ans; }};func findDuplicates(nums []int) []int { ans := []int{} for _, v := range nums { i := v if i < 0 { i = -i } i-- if nums[i] < 0 { ans = append(ans, i+1) } else { nums[i] = -nums[i] } } return ans}from typing import List
class Solution: def findDuplicates(self, nums: List[int]) -> List[int]: ans: List[int] = [] for v in nums: i = abs(v) - 1 if nums[i] < 0: ans.append(i + 1) else: nums[i] = -nums[i] return ansfunction findDuplicates(nums) { const ans = []; for (const v of nums) { const i = Math.abs(v) - 1; if (nums[i] < 0) ans.push(i + 1); else nums[i] = -nums[i]; } return ans;}class Solution { public List<Integer> findDuplicates(int[] nums) { List<Integer> ans = new ArrayList<>(); for (int v : nums) { int i = Math.abs(v) - 1; if (nums[i] < 0) ans.add(i + 1); else nums[i] = -nums[i]; } return ans; }}function findDuplicates(nums: number[]): number[] { const ans: number[] = []; for (const v of nums) { const i = Math.abs(v) - 1; if (nums[i] < 0) ans.push(i + 1); else nums[i] = -nums[i]; } return ans;}Editorial#
Same sign-flip trick as “Find All Numbers Disappeared”. The second occurrence is detected because the slot has already been flagged negative on the first sighting.
Complexity#
- Time:
O(n). - Space:
O(1)extra.
Concept revision#
Related#