1. 程式人生 > 實用技巧 >LeetCode448. 找到所有陣列中消失的數字

LeetCode448. 找到所有陣列中消失的數字

題目要求只能用常數空間和線性時間完成這個任務,因此需要用一個比較取巧的做法。

在沒有空間限制的情況下,我們會想到對每個值做一個對映,比如用一個雜湊表計算每個數出現的次數。但是由於此題對空間進行了限制,
因此我們只能在原陣列上進行“對映”,再由觀察發現,每個數的值都是1~n內的整數,正好可以將值對映到下標。

所以可以這樣:對於一個值nums[i],我們將nums[nums[i]]變為負數,這樣,一遍掃描之後。再進行第二遍掃描。如果某個數j未在陣列中出現過,這nums[j - 1]為正數。

程式碼如下:

class Solution {
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
        int n = nums.size();
        for(int i = 0; i < n; ++i) {
            int pos = abs(nums[i]) - 1;                 // 由於之前nums[i]可能已經變為負數,因此取值時要加上絕對值,減一是因為陣列下標從0開始
            if(nums[pos] > 0) {                        // 如果nums[pos]大於0,將它改為負數
                nums[pos] = -nums[pos];
            }
        }
        vector<int> res;
        for(int i = 0; i < n; ++i) {
            if(nums[i] > 0) {                        // 如果nums[i]是正數,說明原陣列不存在i + 1,因為如果存在i + 1,那麼nums[i]在第一遍掃描的時候會被修改為負數
                res.push_back(i + 1);
            }
        }
        return res;
    }
};