442. Find All Duplicates in an Array 題解
阿新 • • 發佈:2018-12-31
題意:給定一組整數,共n個,這組數字的值均不超過n。在這組數字中,有些數字出現了兩次而其他數字只出現了一次,要求找出該組數字中所有出現兩次的數。並且不能開闢額外的空間,且時間複雜度應為O(n)。
思路:題目不允許開闢額外空間,第一反應是能不能使用位運算/異或來解決該問題,仔細思考後發現似乎行不通。實際上該題目使用的是“藉助陣列下標記錄一些資訊”的思想,題目中“這組數字的值均不超過n”也印證了該想法。總之,該題目的解法是“對於數字n+1,使用下標n處數值的正負進行標記。即使用下標n處數字的正負,來標識數字n+1是否出現過”。
舉例來說,可以使用陣列下標2 處所儲存的數值正負來標識數字3是否已經出現過。當數字3第一次出現時,將下標2處所儲存的數值設定為負。這樣在後續過程中,若數字下標2處的數字為正數,表示3這個數字尚未出現過;若數字下標2處的數字為負數,表示3這個數字已經出現過一次。
本題java程式碼如下:
class Solution { public List<Integer> findDuplicates(int[] nums) { List<Integer> result = new ArrayList<Integer>(); for (int i = 0; i < nums.length; i++) { int currentNum = Math.abs(nums[i]); // 在當前數字對應的下標(當前數字-1)處,使用正負進行標記 // 例如,使用陣列下標2 處所儲存的數值正負來標識數字3是否已經出現過; // 若數字下標2處的數字為正數,表示3這個數字尚未出現過; // 若數字下標2處的數字為負數,表示3這個數字已經出現過一次。 int targetNum = nums[currentNum - 1]; if (targetNum < 0) { result.add(currentNum); } else { nums[currentNum - 1] = -targetNum; } } return result; } }