1. 程式人生 > >LeetCode-442. 陣列中重複的資料

LeetCode-442. 陣列中重複的資料

題目描述

給定一個整數陣列 a,其中1 ≤ a[i] ≤ n (n為陣列長度), 其中有些元素出現兩次而其他元素出現一次

找到所有出現兩次的元素。

你可以不用到任何額外空間並在O(n)時間複雜度內解決這個問題嗎?

示例:

輸入:
[4,3,2,7,8,2,3,1]

輸出:
[2,3]

我的思路(超時)

從第一個數開始查詢,如果第一個數與第二個數相等,將nums[i]放入res,刪除兩個數;若不等,交換兩個數位置,i++,查到最後,刪除nums最後一個元素,從頭開始,程式碼如下:

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

網上思路

給定一個整數陣列 a,其中1 ≤ a[i] ≤ n n為陣列長度)(這個條件非常關鍵!)

從第一個數開始遍歷,對下標為 i 的數,將 nums[ i ] - 1 位置的元素置為負數,後續若出現相同數,則其對應下標的數位負數,將該數放入res陣列;每次取對應下標是應取絕對值(abs)。

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