题目描述
Given an integer array nums
of length n
where all the integers of nums
are in the range [1, n]
and each integer appears once or twice, return an array of all the integers that appears twice.
You must write an algorithm that runs in O(n)
time and uses only constant extra space.
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: []
Constraints:
n == nums.length
1 <= n <= 105
1 <= nums[i] <= n
- Each element in
nums
appears once or twice.
解题思路
【C++解法】
1、负负得正
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
// negate all values
for (int i=0; i<nums.size(); ++i) {nums[i] = -nums[i];}
// make all visitable index positive
for (int i=0; i<nums.size(); ++i) {nums[abs(nums[i])-1] = abs(nums[abs(nums[i])-1]);}
// if index is reachable negate it => two time repeated will get positive and missing will remain negative(from first pass)
for (int i=0; i<nums.size(); ++i) {nums[abs(nums[i])-1] = -nums[abs(nums[i])-1];}
// all positive index left will be solution
vector<int>sol;
for (int i=0; i<nums.size(); ++i) {if (nums[i]>0) {sol.push_back(i+1);}}
return sol;
}
};
2、交换排序
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
int i = 0, n = nums.size();
while(i < n){
if(nums[i] != nums[nums[i]-1]) swap(nums[i], nums[nums[i]-1]);
else i++;
}
vector<int> res;
for(i=0; i<n; i++){
if(nums[i] != i+1) res.push_back(nums[i]);
}
return res;
}
};
3、哈希标记
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
vector<int>res;
int i = 0;
for(int i=0; i<nums.size(); i++) {
int index = abs(nums[i]) - 1;
if(nums[index]<0) {res.push_back(abs(nums[i]));}
else {nums[index] = -nums[index];}
}
return res;
}
};
【Java解法】
1、负负得正
class Solution {
public List<Integer> findDuplicates(int[] nums) {
List<Integer> res = new ArrayList<Integer>();
for (int i=0; i<nums.length; i++) {nums[i] = -nums[i];}
for (int i=0; i<nums.length; i++) {nums[Math.abs(nums[i])-1] = Math.abs(nums[Math.abs(nums[i])-1]);}
for (int i=0; i<nums.length; i++) {nums[Math.abs(nums[i])-1] = -nums[Math.abs(nums[i])-1];}
for (int i=0; i<nums.length; i++) {if (nums[i]>0) {res.add(i+1);}}
return res;
}
}
2、交换排序
class Solution {
public List<Integer> findDuplicates(int[] nums) {
List<Integer> res = new ArrayList<Integer>();
int i = 0, n = nums.length;
while(i < n){
if(nums[i] != nums[nums[i]-1]) {nums = swap(nums, i, nums[i]-1);}
else i++;
}
for(i=0; i<n; i++) {if(nums[i] != i+1) res.add(nums[i]);}
return res;
}
public static int[] swap(int[] nums, int a,int b){
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
return nums;
}
}
3、哈希标记
class Solution {
public List<Integer> findDuplicates(int[] nums) {
List<Integer> res = new ArrayList<Integer>();
for(int i=0; i<nums.length; i++) {
int index = Math.abs(nums[i]) - 1;
if(nums[index]<0) {res.add(Math.abs(nums[i]));}
else {nums[index] = -nums[index];}
}
return res;
}
}
参考文献