一.前言
一直以來,算法學來學去,但是真正解題的時候,卻運用不上來,在項目conding的時候,也不會想到。歸根結底還是缺乏了必要的練習,現在開始刷leetcode,從頭開始,堅持每天一題。
二.題目
題目:給定一個整數數組 nums 和一個目標值 target,請你在該數組中找出和為目標值的那 兩個 整數,並返回他們的數組下標。
你可以假設每種輸入只會對應一個答案。但是,你不能重復利用這個數組中同樣的元素。
示例:給定 nums = [2, 7, 11, 15], target = 9,因為 nums[0] + nums[1] = 2 + 7 = 9,所以返回 [0, 1]
三.解題思路
1.常見思路:這個題的最容易想到的就是暴力解法,兩層循環,第一層中依次取出數組中的每個元素,第二層中依次取出第一層數組元素之后的元素,然后兩個數相加與目標值target進行對比。代碼如下:
1 class Solution { 2 public int[] twoSum(int[] nums, int target) { 3 for(int i = 0; i < nums.length; i++){ 4 for(int j = i + 1; j < nums.length; j++){ 5 if(nums[i] + nums[j] == target){ 6 return new int[] {i, j}; 7 } 8 } 9 } 10 throw new IllegalArgumentException("No two sum solution"); 11 } 12 }
該解法的空間復雜度是 O(1),時間復雜度是O(n^2);
2.第二種解題思路是借助了哈希表,第一次迭代先將數組中所有元素,以及元素所對應的下標存進哈希表中,然后第二次迭代時,依次取出數組中的元素,計算出該元素與目標值target的差值,查看該差值是否在哈希表中,如果存在並且下標不是本次比較的元素(不能重復利用同一個元素),則返回該值和差值所對應的下標。代碼如下:
1 class Solution { 2 public int[] twoSum(int[] nums, int target) { 3 Map<Integer, Integer> hashMap = new HashMap(); 4 for(int i = 0; i < nums.length; i++){ 5 hashMap.put(nums[i], i); 6 } 7 for(int i = 0; i < nums.length; i++){ 8 int num = target - nums[i]; 9 if(hashMap.containsKey(num) && hashMap.get(num) != i){ 10 return new int[] {i, hashMap.get(num)}; 11 } 12 } 13 throw new IllegalArgumentException("no two sum solution"); 14 } 15 }
該解法的空間復雜度為O(n),時間復雜度也為O(n);
3.看到上面這種解法的時候,有的人可能就會想到了既然不能重復利用同一個元素,那么是不是能先進行比較,再把元素放進哈希表中呢?這就是我們的第三中解法,只使用一次迭代。和前面一樣,先計算差值,然后去哈希表中查找,如果存在則返回結果,不存在則把該元素放入哈希表中。代碼如下:
1 class Solution { 2 public int[] twoSum(int[] nums, int target) { 3 Map<Integer, Integer> hashMap = new HashMap(); 4 for(int i = 0; i < nums.length; i++){ 5 int num = target - nums[i]; 6 if(hashMap.containsKey(num)){ 7 return new int[] {i, hashMap.get(num)}; 8 } 9 hashMap.put(nums[i], i); 10 } 11 throw new IllegalArgumentException("no two sum solution"); 12 } 13 }
