[LeetCode] Find All Duplicates in an Array 找出陣列中所有重複項
阿新 • • 發佈:2018-12-27
Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
Find all the elements that appear twice in this array.
Could you do it without extra space and in O(n) runtime?
Example:
Input: [4,3,2,7,8,2,3,1] Output: [2,3]這道題給了我們一個數組,陣列中的數字可能出現一次或兩次,讓我們找出所有出現兩次的數字,由於之前做過一道類似的題目
解法一:
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]; } returnres; } };
下面這種方法是將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不等,那麼我們將nums[i]存入結果res中即可,參見程式碼如下:
解法二:
class Solution { public: vector<int> findDuplicates(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(nums[i]); } return res; } };
下面這種方法是在nums[nums[i]-1]位置累加陣列長度n,注意nums[i]-1有可能越界,所以我們需要對n取餘,最後要找出現兩次的數只需要看nums[i]的值是否大於2n即可,最後遍歷完nums[i]陣列為[12, 19, 18, 15, 8, 2, 11, 9],我們發現有兩個數字19和18大於2n,那麼就可以通過i+1來得到正確的結果2和3了,參見程式碼如下:
解法三:
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; } };
類似題目:
參考資料: