442. **Find All Duplicates in an Array
https://leetcode.com/problems/find-all-duplicates-in-an-array/description/
题目描述
Given an array of integers, 1 ≤ a[i] ≤ n
(n = size of array
), some elements appear twice and others appear once.
Find all the elements that appear twice in this array.
Could you do it without extra space and in O ( n ) O(n) O(n) runtime?
Example:
Input:
[4,3,2,7,8,2,3,1]
Output:
[2,3]
解题思路
找出数组中所有的重复数字. 这道题可以认为承接 448. *Find All Numbers Disappeared in an Array.
注意到数组中的元素的范围在 1 ~ N
, 所以, 可以考虑使用将 nums[nums[i] - 1]
的值设置为负数的做法.
考虑上面这个数组:
# 假设数组的索引从 1 开始
index : 1 2 3 4 5 6 7 8
value : 4 3 2 7 8 2 3 1
现在从索引 1
开始, 如果依次将 a[abs(a[i])]
的值改为负数, 但如果 a[abs(a[i])]
已经是负数了, 那么就不用修改了. 当 index = 6
时, 问题就出现了, 下图用 |6|
标注出来了.
# 假设数组的索引从 1 开始
index : 1 2 3 4 5 |6| 7 8
value : 4 -3 -2 -7 8 2 -3 -1
因为此时 nums[nums[6]]
即 nums[2]
已经是负数了, 另外可以观察到如果 index
进行到 7
的时候, nums[nums[7]]
即 nums[3]
的值也是负数, 而 2, 3
就是我们要找的重复数字, 我们便意识到, 如果当 nums[abs(nums[i])]
已经是负数了, 我们就需要把 abs(nums[i])
给记录下来, 因为它就是重复数字.
这类题目就是要举一些例子, 然后找出规律.
C++ 实现 1
时间复杂度为 O ( n ) O(n) O(n).
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
vector<int> res;
for (int i = 0; i < nums.size(); ++i) {
int index = std::abs(nums[i]) - 1;
if (nums[index] < 0) res.push_back(std::abs(nums[i]));
else nums[index] *= -1;
}
return res;
}
};