数组中重复的数据

442. 数组中重复的数据

给你一个长度为 n的整数数组 nums,其中 nums的所有整数都在范围[1, n] 内,且每个整数出现 一次 或 两次 。请你找出所有出现 两次 的整数,并以数组形式返回。

你必须设计并实现一个时间复杂度为 O(n)且仅使用常量额外空间的算法解决此问题。

示例:

输入:nums = [4,3,2,7,8,2,3,1]

输出:[2,3]

思路:

首先我们先想到的是用哈希表保存已经出现过的数字次数。这就不符合题目要求的空间复杂度O(1)

对数组排序时间复杂度为O(NlogN)也不符合。

所以我们只有「原地修改数组」了。

我们注意到数组长度为n,每个数据的取值访问为[1,n]

我们只需要把这个数放到它应该要到的位置。当然这里我们不是真的放,而是把应在的位置的值取反。

  • 从起始位置进行遍历,每次将下标为nums[i]−1 的数字取反;
  • 当遍历到值 nums[i] - 1为负数,需要忽略其负号。
  • 若发现下标为nums[i]的数字已经是负数,说明之前出现过同样的数字 nums[i],即找到了重复数字;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
int n = nums.size();
vector<int> res;
for(int i = 0; i < n; i++){
//为负数,代表已经出现过
if(nums[abs(nums[i]) - 1] < 0){
res.push_back(abs(nums[i]));
}
//应在的位置取反
nums[abs(nums[i]) - 1] *= -1;
}
return res;
}
};