1. 程式人生 > >442. Find All Duplicates in an Array

442. Find All Duplicates in an Array

給的條件是 1 ≤ a[i] ≤ n (n = size of array),第一反應就是在下標上做文章。

方法一: 如果數字和下標不對應則把數字換到對應的下標那裡,迴圈一遍後下標和數字不對應說明不存在下標的數字,下標中存的一定是重複的。但是我不確定時間複雜度是O(2n)還是可以約等於O(n)。

class Solution {
public:
    vector<int> findDuplicates(vector<int>& nums) {
        vector<int> res;
        int i = 0;
        while (i < nums.size()) {
            if (nums[i] != nums[nums[i]-1]) swap(nums[i], nums[nums[i]-1]);
            else i++;
        }
        for (i = 0; i < nums.size(); i++) {
            if (nums[i] != i + 1) res.push_back(nums[i]);
        }
        return res;
    }
};

方法二: 對於每個nums[i],我們將其對應的nums[nums[i] - 1]取相反數,如果其已經是負數了,說明之前存在過,我們將其加入結果res中即可。  

class Solution {
public:
    vector<int> findDuplicates(vector<int>& nums) {
        vector<int> res;
        for (int i = 0; i < nums.size(); ++i) {
            int idx = abs(nums[i]) - 1;
            if (nums[idx] < 0) res.push_back(idx + 1);
            nums[idx] = -nums[idx];
        }
        return res;
    }
};

方法三: 和方法二類似,不是取負數而是加上陣列長度。注意每次要取數字的時候先求餘才是陣列原本的數字(後面的數已經在前面的時候加過n了),方法二取的時候也要取絕對值,道理是一樣的。如果最後結果大於2n了則說明有重複數字。  

class Solution {
public:
    vector<int> findDuplicates(vector<int>& nums) {
        vector<int> res;
        int n = nums.size();
        for (int i = 0; i < n; ++i) {
            nums[(nums[i] - 1) % n] += n;
        }
        for (int i = 0; i < n; ++i) {
            if (nums[i] > 2 * n) res.push_back(i + 1);
        }
        return res;
    }
};