leetcode 442 陣列中重複的資料
阿新 • • 發佈:2018-11-16
給定一個整數陣列 a,其中1 ≤ a[i] ≤ n (n為陣列長度), 其中有些元素出現兩次而其他元素出現一次。
找到所有出現兩次的元素。
你可以不用到任何額外空間並在O(n)時間複雜度內解決這個問題嗎?
示例:
輸入: [4,3,2,7,8,2,3,1] 輸出: [2,3]
顯然,若可以使用額外空間,利用set的特性,判斷nums[i]是否存在set中,若存在則此數時重複的,記錄下來並將set中的該數刪除,若不存在則將其放入set中即可。
class Solution { public List<Integer> findDuplicates(int[] nums) { List<Integer> res = new ArrayList<>(); Set<Integer> set = new TreeSet<>(); for(int num:nums){ if(set.contains(num)){ res.add(num); set.remove(num); } else{ set.add(num); } } return res; } }
另外,考慮不使用額外空間的演算法:
題目中沒有提到不能改變陣列元素的值,因此可以利用元素的正負性來進行技術。同時,因為1<=nums[i]<=n,所以每個元素都對應著另一個元素的索引,當我們遍歷到nums[i]時,將Math.abs(nums[i]-1)對應的元素取反,意味著nums[i]出現一次,如果nums[Math.abs(nums[i])-1]的值在取反之後變回正值,則說明在此之前nums[i]已經出現過了,將nums[i]記錄下來即可。
class Solution { public List<Integer> findDuplicates(int[] nums) { for(int i=0;i<nums.length;i++){ int tmp=Math.abs(nums[i]); nums[tmp-1]=-nums[tmp-1]; if(nums[tmp-1]>0){ res.add(tmp); } } return res; } }