问题描述
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) runtime?
Example:
Input:
[4,3,2,7,8,2,3,1]
Output:
[2,3]
算法简介
因为有1 ≤ a[i] ≤ n的限制条件,所以整个算法就是在使得a[i] = i+1。具体的,遍历每个位置,将不属于该位置的元素归位,如果该元素理应存在的位置已经有一个正确的元素,那么就出现重复,将重复元素废弃(将值设为一个非法值如-1)。整个算法做了遍历操作(O(N))以及将元素归位(O(N)),所以整体也是O(N)。
代码
void swap(int& a,int& b) {
int c = a;
a = b;
b = c;
}
vector<int> findDuplicates(vector<int>& nums) {
int s = nums.size();
vector<int> result;
for (int i = 0;i < s;++i) {
while (nums[i] != -1 && nums[i] != i+1) {
if (nums[nums[i]-1] == nums[i]) {
result.push_back(nums[i]);
nums[i] = -1;
}
else
swap(nums[i],nums[nums[i]-1]);
}
}
sort(result.begin(),result.end());
return result;
}