LeetCode集錦(一) - two sum
Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input would have exactly one solution, and you may not use the same element twice. Example: Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1]. 複製程式碼
翻譯:
給定一個整數陣列,返回兩個數字的索引,使它們加起來等於一個特定的目標。
您可以假設每個輸入都只有一個解決方案,並且不能兩次使用相同的元素。
給定陣列:[2, 7, 11, 15] ,兩數和為:9
因為按順序而言,2+7等於9,所以選擇2和7對應的下標,0,1構成新陣列。返回結果為[0,1]
解題思路
本題字面含義其實是求和,找尋兩個數字的和為目標值,然後輸出該兩個數字的下標值。
換一個角度而言,我們這邊有一個最終結果值--目標值,和一系列待選值--陣列,如果我們在待選值中選擇一個值,由目標值減去改值,就是另外需要尋找的值。這樣我們就拿到全部需要的結果,需要做的只是從待選值中,查詢那個差值。
解題方法
-
第一種解體方法,按照我們的思路來編輯,程式碼如下
for (int i = 0; i < nums.length; i++) { int differ = target - nums[i]; for (int m = i + 1; m < nums.length; m++) { if (differ == nums[m]) { return new int[]{i, m}; } } } return new int[]{}; 複製程式碼
時間複雜度: 該方案用了兩層巢狀迴圈,第一層迴圈度為n,第二層迴圈度也是n-m,所以f(n)=n*(n-m)=n^2-mn;所以O(f(n))=O(n^2),即T(n)=O(n^2)
空間複雜度: 該方案並沒有使用額外度空間去儲存,所以空間複雜度還是O(1);
-
第二種解題方法,是延伸出來,既然我們要尋找另外一個值,是否可以用map這類資料結構來方便查詢呢?程式碼如下:
//先轉化為hashmap Map<Integer, Integer> map = new HashMap<>(nums.length); for (int i = 0; i < nums.length; i++) { map.put(nums[i], i); } for (int i = 0; i < nums.length; i++) { Integer integer = map.get(target - nums[i]); //如果是本身,就跳過 if (integer != null && integer!=i) { return new int[]{i, integer}; } } return new int[]{}; 複製程式碼
時間複雜度: 該方案用了單層迴圈,兩次單層迴圈,所以f(n)=n+n=2n;所以O(f(n))=O(2n)=O(n),即T(n)=O(n)
空間複雜度: 該方案使用了HashMap去儲存數值和索引的關係,所以是原來陣列的近似2倍(這邊不考慮因為資料結構而導致的開銷),即為2n,所以總共的空間複雜度為O(f(n))=O(3n)=O(n),所以空間複雜度還是O(n);
-
第三種解題方案是針對與第二種解題優化的,第二種方案是直接把陣列轉化為map,所以這部分的空間開銷是固定,如果我們可以一邊讀取,一邊儲存,那麼是否可以更加簡單呢?因為9-2=7,相對的9-7=2。所以按照這種思路,出現了第三種解題方案,程式碼如下:
Map<Integer, Integer> map = new HashMap<>(nums.length); for (int i = 0; i < nums.length; i++) { int differ = target - nums[i]; Integer result = map.get(differ); if (null != result) { return new int[]{result,i }; } map.put(nums[i], i); } return new int[]{}; 複製程式碼
總結
本題的大致解法如上所訴,但是可以更改的方式很多,如果輸入的陣列出現重複的情況,那麼方法2是一個致命的錯誤解法,因為會把它覆蓋,所以個人覺得,方法三是相對較優的一種解法。