英特爾 12 代酷睿超低壓處理器現身:2 大核 8 小核,二合一筆記本將搭載
阿新 • • 發佈:2021-11-17
一、 Two Sum
1、題目描述
給定一個整數陣列 nums 和一個整數目標值 target,請你在該陣列中找出 和為目標值 target 的那 兩個 整數,並返回它們的陣列下標。
你可以假設每種輸入只會對應一個答案。但是,陣列中同一個元素在答案裡不能重複出現。
你可以按任意順序返回答案。
示例:
輸入:nums = [2,7,11,15], target = 9
輸出:[0,1]
解釋:因為 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
2、解法一:
暴力解法,直接遍歷陣列所有元素,找到其中兩個值等於目標值,返回下標。
public static int[] twoNumAdd(int nums[], int target) { int ans[] = new int[2]; for (int i = 0; i < nums.length; i++) { for (int j = i + 1; j < nums.length; j++) { if (nums[i] + nums[j] == target) { ans[0] = i; ans[1] = j; } } } return ans; }
這個解法是兩層for迴圈遍歷:時間複雜度為O(n²)
空間複雜度為O(1)
3、解法二:
分析解法一:
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
ans[0] = i;
ans[1] = j;
}
}
換種思路解決這個問題
兩數相加等於目標和。 a + b = c;
等式變換:a = c - b。
程式碼可以改成:
for (int j = i + 1; j < nums.length; j++) { sub = target - num[i]; if (nums[j] == sub) { ans[0] = i; ans[1] = j; } }
這樣無非就是解決這個問題的思路有所變化,程式碼還是需要兩個for迴圈。
怎麼樣只需要一個for迴圈就解決不需要兩個for迴圈?
有沒有一種方法,不用遍歷就可以找到元素裡有沒有等於 sub 的?
考慮我們java基礎中學到Map集合的實現類HashTable。
HashTable:HashTable不允許鍵或值為null。
public static int[] twoNumAddHashTable(int nums[], int target) { Map<Integer,Integer> map = new Hashtable<>(); //將陣列的元素存放在HashMap裡面,key值儲存nums的值,value儲存陣列下標 for (int i = 0; i < nums.length; i++) { map.put(nums[i],i); } for (int i = 0; i < nums.length; i++) { int sub = target - nums[i]; //題目要求陣列中同一個元素在答案裡不能重複出現。所以需要判斷是否是當前陣列下標對應的值 if (map.containsKey(sub) && map.get(sub) != i){ return new int[]{i,map.get(sub)}; } } throw new IllegalArgumentException("No two sum solution"); }
此時:缺少一個for迴圈巢狀,時間複雜度變成O(n)
空間複雜度:由於開闢的Hashtable的空間,空間複雜度變為 O(n) 所謂的空間換時間
4、方法三
方法二中兩個for迴圈是一樣的,我們可以想,如何用一個for迴圈就完成,讓程式碼更簡潔。
public static int[] twoNumAddHashTable2(int nums[], int target) {
Map<Integer,Integer> map = new Hashtable<>();
for (int i = 0; i < nums.length; i++) {
int sub = target - nums[i];
//題目要求陣列中同一個元素在答案裡不能重複出現,當前元素還沒有存放到Map中,所以不需要判斷。
if (map.containsKey(sub)){
return new int[]{i,map.get(sub)};
}
map.put(nums[i],i);
}
throw new IllegalArgumentException("No two sum solution");
}
5、尊重原創,學習有度。
在此宣告一下,關於LeetCode演算法題,都引用在這。如有侵權,請聯絡刪除。