乘風破浪:LeetCode真題_001_TwoSum

乘風破浪:LeetCode真題_001_TwoSum

1、前言

    沉寂了很長時間,也悟出了不少的道理,寫做是一種業餘的愛好,是一種本身之後學習的工具,是對本身過往的經驗積累的佐證,是檢驗本身理解深刻度的方法。在前面的模塊之中,咱們已經將基本的編程知識、數據結構、設計模式、應用框架、各類優化爛熟於心了,對程序開發有了必定的理解,可是編程的功力是一種水磨的功夫,須要問題,也須要思考,最重要的是須要本身用心的去打出代碼,在這個過程當中經驗、技巧、熟練度、思考力都是很是重要的,所以咱們經過LeetCode上的一些題目來鍛鍊一下這方面的能力。java

2、LeetCode真題_001_TwoSum

2.1 題目

2.2 分析與解決

    其實從問題咱們就能夠看出,這是相似於helloworld的一個題目,比較簡單,藉以引導咱們從不一樣的角度使用不一樣的方法去解決問題。最簡單的想法就是暴力破解方法,經過窮舉全部的狀況來解決問題,可是代價是時間複雜度O(n~2),空間複雜度O(1)。那麼有沒有其餘方法呢,因而咱們想到了hash表的方法,用空間換時間,經過一次遍歷就能找到全部的可能結果。算法

  經過暴力算法來解決:編程

 1 public int[] twoSum(int[] nums, int target) {  2     for (int i = 0; i < nums.length; i++) {  3         for (int j = i + 1; j < nums.length; j++) {  4             if (nums[j] == target - nums[i]) {  5                 return new int[] { i, j };  6  }  7  }  8  }  9     throw new IllegalArgumentException("No two sum solution"); 10 }

    經過hash算法來解決,又分爲兩次for循環和一次for循環:設計模式

public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        map.put(nums[i], i);
    }
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (map.containsKey(complement) && map.get(complement) != i) {
            return new int[] { i, map.get(complement) };
        }
    }
    throw new IllegalArgumentException("No two sum solution");
}

 1 public int[] twoSum(int[] nums, int target) {  2     Map<Integer, Integer> map = new HashMap<>();  3     for (int i = 0; i < nums.length; i++) {  4         int complement = target - nums[i];  5         if (map.containsKey(complement)) {  6             return new int[] { map.get(complement), i };  7  }  8  map.put(nums[i], i);  9  } 10     throw new IllegalArgumentException("No two sum solution"); 11 }

    來看看咱們的算法:數組

 1 import java.util.Arrays;  2 
 3 public class Solution {  4     private static class Node implements Comparable<Node> {  5         int val;  6         int idx;  7 
 8         public Node() {  9  } 10 
11         public Node(int val, int idx) { 12             this.val = val; 13             this.idx = idx; 14  } 15 
16  @Override 17         public int compareTo(Node o) { 18             if (o == null) { 19                 return -1; 20  } 21             return this.val - o.val; 22  } 23  } 24 
25 
26     /**
27  * 題目大意 28  * 給定一個整數數組,找出其中兩個數知足相加等於你指定的目標數字。 29  * 要求:這個函數twoSum必需要返回可以相加等於目標數字的兩個數的索引,且index1必需要小於index2。 30  * 請注意一點,你返回的結果(包括index1和index2)都不是基於0開始的。你能夠假設每個輸入確定只有一個結果。 31  * 32  * 解題思路 33  * 建立一個輔助類數組,對輔助類進行排序,使用兩個指針,開始時分別指向數組的兩端,看這兩個下標對應的值是否 34  * 等於目標值,若是等於就從輔助類中找出記錄的下標,構造好返回結果,返回。若是大於就讓右邊的下標向左移, 35  * 進入下一次匹配,若是小於就讓左邊的下標向右移動,進入下一次匹配,直到全部的數據都處理完 36      */
37 
38     public int[] twoSum(int[] nums, int target) { 39         int[] result = {0, 0}; 40 
41         Node[] tmp = new Node[nums.length]; 42         for (int i = 0; i < nums.length; i++) { 43             tmp[i] = new Node(nums[i], i); 44  } 45 
46  Arrays.sort(tmp); 47 
48         int lo = 0; 49         int hi = nums.length - 1; 50 
51 
52         while (lo < hi) { 53             if (tmp[lo].val + tmp[hi].val == target) { 54 
55                 if (tmp[lo].idx > tmp[hi].idx) { 56                     result[0] = tmp[hi].idx ; 57                     result[1] = tmp[lo].idx ; 58                 } else { 59                     result[0] = tmp[lo].idx ; 60                     result[1] = tmp[hi].idx ; 61  } 62                 break; 63             } else if (tmp[lo].val + tmp[hi].val > target) { 64                 hi--; 65             } else { 66                 lo++; 67  } 68  } 69         return result; 70  } 71 }

    這種想法也比較巧妙,先對全部元素進行排序,而後經過定義首尾兩個指針來不斷地逼近最後的和,直至遍歷完成,很是的巧妙,時間複雜度O(n),空間複雜度O(n)。不過也增長了額外的建立對象的空間。數據結構

 

 

 

3、總結

    經過這個簡單的問題,咱們明白了對於一件事情,要麼使用時間換取空間,要麼使用空間換取時間,最後達到咱們想要的結果,每每經過空間換取時間的比較多,所以hash算法就變得很是的重要了,固然也有其餘的算法。框架

相關文章
相關標籤/搜索