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]
這道題讓我們找出數組中所有消失的數,跟之前那道Find All Duplicates in an Array極其類似,那道題讓找出所有重復的數字,這道題讓找不存在的數,這類問題的一個重要條件就是1 ≤ a[i] ≤ n (n = size of array),不然很難在O(1)空間和O(n)時間內完成。三種解法也跟之前題目的解法極其類似。首先來看第一種解法,這種解法的思路路是,對於每個數字nums[i],如果其對應的nums[nums[i] - 1]是正數,我們就賦值為其相反數,如果已經是負數了,就不變了,那么最后我們只要把留下的整數對應的位置加入結果res中即可,參見代碼如下:
解法一:
class Solution { public: vector<int> findDisappearedNumbers(vector<int>& nums) { vector<int> res; for (int i = 0; i < nums.size(); ++i) { int idx = abs(nums[i]) - 1; nums[idx] = (nums[idx] > 0) ? -nums[idx] : nums[idx]; } for (int i = 0; i < nums.size(); ++i) { if (nums[i] > 0) { res.push_back(i + 1); } } return res; } };
第二種方法是將nums[i]置換到其對應的位置nums[nums[i]-1]上去,比如對於沒有缺失項的正確的順序應該是[1, 2, 3, 4, 5, 6, 7, 8],而我們現在卻是[4,3,2,7,8,2,3,1],我們需要把數字移動到正確的位置上去,比如第一個4就應該和7先交換個位置,以此類推,最后得到的順序應該是[1, 2, 3, 4, 3, 2, 7, 8],我們最后在對應位置檢驗,如果nums[i]和i+1不等,那么我們將i+1存入結果res中即可,參見代碼如下:
解法二:
class Solution { public: vector<int> findDisappearedNumbers(vector<int>& nums) { vector<int> res; for (int i = 0; i < nums.size(); ++i) { if (nums[i] != nums[nums[i] - 1]) { swap(nums[i], nums[nums[i] - 1]); --i; } } for (int i = 0; i < nums.size(); ++i) { if (nums[i] != i + 1) { res.push_back(i + 1); } } return res; } };
下面這種方法是在nums[nums[i]-1]位置累加數組長度n,注意nums[i]-1有可能越界,所以我們需要對n取余,最后要找出缺失的數只需要看nums[i]的值是否小於等於n即可,最后遍歷完nums[i]數組為[12, 19, 18, 15, 8, 2, 11, 9],我們發現有兩個數字8和2小於等於n,那么就可以通過i+1來得到正確的結果5和6了,參見代碼如下:
解法三:
class Solution { public: vector<int> findDisappearedNumbers(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] <= n) { res.push_back(i + 1); } } return res; } };
類似題目:
Find All Duplicates in an Array
參考資料:
https://discuss.leetcode.com/topic/65944/c-solution-o-1-space
https://discuss.leetcode.com/topic/66063/5-line-java-easy-understanding