LeetCode [448. Find All Numbers Disappeared in an Array] 難度[easy]

題目

Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.

Find all the elements of [1, n] inclusive that do not appear in this array.

Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.

Example:

Input:
[4,3,2,7,8,2,3,1]

Output:
[5,6]


解題思路

題目大意如下:給定一個整型數組,數組元素的大小都在 1 到 n 之間,其中 n 為數組大小。元素可能出現一次或者兩次,現在希望你能找出不屬于該數組,但大小為[1,n]的元素,要求你的算法不需要使用額外的空間,并且時間復雜度為 O(n) 。

題目的難點主要在于限定你設計的算法空間復雜度為 O(1), 時間復雜度為 O(n)。一開始自己直觀的想法就是先建立一個大小為 n 的布爾型數組,初始化為false,然后遍歷一遍輸入數組,將出現的元素對應的布爾值修改為true,最后只需再遍歷一遍布爾型數組,布爾值為false的數組下標即為體重所求元素。雖然該算法的時間復雜度為 O(n), 但空間復雜度也為 O(n), 顯然不滿足題意。

于是改變思路,既然不能使用額外空間,而且不可能只遍歷一遍就可得到答案(至少需要兩次循環,每次循環都能得到一定量的信息),那么原數組肯定需要發生一些改變來存儲第一次遍歷后得到的信息。沿著這個思路,不難想出正確的算法,其中之一,如下所述:第一次循環將數組中元素作為下標對應的元素值變為負數,第二次循環判斷元素值是否大于 0 , 大于 0 的話,說明其下標即為缺失值(在第一次循環中已經將出現過元素作為下標對應的元素值變為負數了,好像有點繞口 ORZ ,待會看看代碼就應該很好理解了)。該算法空間復雜度為 O(1), 時間復雜度為 O(n), 滿足題意。


參考代碼

class Solution {
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
        int len = nums.size();
        for(int i=0; i<len; i++) {
            int m = abs(nums[i])-1; // index start from 0
            nums[m] = nums[m]>0 ? -nums[m] : nums[m];
        }
        vector<int> res;
        for(int i = 0; i<len; i++) {
            if(nums[i] > 0) res.push_back(i+1);
        }
        return res;
    }
};
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容