The description of problem
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.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-all-duplicates-in-an-array
an example
Input: nums = [4,3,2,7,8,2,3,1]
Output: [2,3]
Solution 1
intuition
use positive and negative signs to indicate the appearance times for a specific element.
specifically, when you just found a elements nums[i], we could use minus sign add to the nums[nums[i] - 1]
easily to see, when you just found the second elements in your array, you will do the above operation once again.
The codes
#include <vector>
#include <iostream>
#include <cmath>
using namespace std;
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
vector<int> res;
for (auto num : nums) {
int flag_pos = abs(num) - 1;
if (nums[flag_pos] < 0) {
res.push_back(abs(num));
} else {
nums[flag_pos] = -nums[flag_pos];
}
}
return res;
}
};
int main()
{
Solution s;
vector<int> nums = {4,3,2,7,8,2,3,1};
vector<int> res = s.findDuplicates(nums);
for (int i = 0; i < res.size(); i++) {
cout << res[i] << " ";
}
cout << endl;
}
The corresponding results
2 3
The solution 2
The intuition
use the data structure of map to find the elements appearing twice in the array
The codes
#include <vector>
#include <iostream>
#include <unordered_map>
using namespace std;
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
vector<int> res;
// initialize a hash table with 0
unordered_map<int, int> hash;
for (auto num : nums) {
if (hash[num] == 1) {
res.emplace_back(num);
} else {
hash[num] = 1;
}
}
return res;
}
};
int main()
{
Solution s;
vector<int> nums = {4,3,2,7,8,2,3,1};
vector<int> res = s.findDuplicates(nums);
for (int i = 0; i < res.size(); i++) {
cout << res[i] << " ";
}
cout << endl;
}