Original: https://dushusir.com/leetcode-find-all-duplicates-in-an-array/
question
You are given an array of integers nums
n
where all integers of nums
are in the range [1, n]
, and each integer occurs once or . Please find all the integers where appears twice and return it as an array.
You have to design and implement an algorithm with time complexity O(n)
and using only constant extra space to solve this problem.
Example 1:
input: nums = [4,3,2,7,8,2,3,1]
output: [2,3]
Example 2:
input: nums = [1,1,2]
output: [1]
Example 3:
input: nums = [1]
output: []
Tip:
n == nums.length
1 <= n <= 105
1 <= nums[i] <= n
- Each element in
nums
occurs once or twice
Solution one
Ideas:
Using the unique feature of the Set
value, continuously add the numbers in nums
to an empty Set
, and then use the set.add
method to determine whether there are duplicate numbers by obtaining whether the length of set
has increased.
:
/**
* @param {number[]} nums
* @return {number[]}
*/
var findDuplicates = function(nums) {
const set = new Set() // 唯一值检验
const result = [] // 结果数组
nums.forEach(n => {
const preSize = set.size
// 使用 set.add 方法,通过获取 set 长度是否增加来判断是否有重复数字出现
set.add(n)
// 发现重复数字
if(preSize === set.size){
result.push(n)
}
})
return result
};
Solution two
ideas:
Traverse the entire array, treat each number as the array position information, and then reverse the number corresponding to each position to a negative number, which is equivalent to making a mark, indicating that the position corresponding to this number is already occupied by a number, and we will meet again next time If this number is found to be negative, it means that it has already appeared.
For example [4,3,2,7,8,2,3,1]
, went first 2
when the inverted position as 1
digital 3
is -3
, go to the next 2
time, will be able to find the location for the 1
figures for -3
, has been flipped over, show digital 2
appeared twice.
Code:
/**
* @param {number[]} nums
* @return {number[]}
*/
var findDuplicates = function(nums) {
let result = [];
for (let i = 0; i < nums.length; i++) {
let num = Math.abs(nums[i]);
if (nums[num - 1] > 0) {
/**
把数字翻转为负数的目的是,做一个标识,表明这个数字对应的位置,已经有数字占用了,下一次再遇到这个数字如果发现是负数就表明已经出现过
比如[4,3,2,7,8,2,3,1]
走到第一个2的时候,位置为1的数字为3,将3翻转为-3,走到下一个2的时候,翻转3的时候发现已经被翻转过了
*/
nums[num - 1] *= -1;
} else {
result.push(num);
}
}
return result;
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。