LeetCode的第一題能夠說是開胃菜,它的難度還不至於嚇退一個誠心要刷題的人,也能給新來的一點信心。就從它開始LeetCode之旅吧。java
題目:兩數之和算法
描述:給定一個整數數組 nums 和一個目標值 target,請你在該數組中找出和爲目標值的那兩個整數,並返回他們的數組下標。你能夠假設每種輸入只會對應一個答案。可是,你不能重複利用這個數組中一樣的元素。數組
示例:學習
這個題目看起來並不複雜,咱們只須要在數組中找到兩個數相加以後等於target的值便可。可能咱們許多人第一個想法就是雙重for循環,也就是下面的解法一:暴力查找的方式。測試
用外層循環選定一個值,用內層循環判斷它們的和是否等於target。示例代碼以下:code
public int[] twoSum(int[] nums, int target) { int len = nums.length; for (int i = 0; i < len; i++) { for (int j = i + 1; j < len & j != i; j++) { if (nums[i] + nums[j] == target) { return new int[] { i, j }; } } } return null; }
這一解法很簡單,也很符合咱們的思惟方式,可是它對於計算機來講就不那麼友好了。這個算法的時間複雜度爲O(n<sup>2</sup>),雖然用它能夠經過測試,可是在面對很大數組時就再也不適用,咱們應該考慮更高效的方式。blog
能夠發現,促使咱們適用雙重for循環的主要緣由在於咱們知道每一個數字的下標,可是不知道它們的值,數組自己就是根據下標獲取值容易,而查找較難。若是咱們能把下標和值對應起來,就能夠解決數組的這一問題,因此考慮使用哈希表。哈希表的特性偏偏能夠解決數組查詢慢的問題,因而有了如下代碼:圖片
public int[] twoSumOptimize(int[] nums, int target) { int len = nums.length; Map<Integer, Integer> map = new HashMap(len); for (int i = 0; i < len; i++) { map.put(nums[i], i); } for (int i = 0; i < len; i++) { int temp = target - nums[i]; if (map.containsKey(temp) && map.get(temp) != i) { return new int[] { i, map.get(temp) }; } } return null; }
由於要把數組轉存成哈希表,因此空間複雜度增長到了O(n),但也由於哈希表的查詢優點,時間複雜度下降到了O(n)。由於時間複雜度下降的幅度很大,因此這是值得的。資源
若是追求簡練的代碼,上述兩次for循環還能夠合併成一個,代碼以下所示:get
public int[] twoSumOptimize(int[] nums, int target) { int len = nums.length; Map<Integer, Integer> map = new HashMap(len); for (int i = 0; i < len; i++) { int temp = target - nums[i]; if (map.containsKey(temp) && map.get(temp) != i) { return new int[] { map.get(temp), i }; } map.put(nums[i], i); } return null; }
這個簡單的題目給咱們啓示:符合咱們思惟的算法最容易想到,但對計算機不必定高效。而經過各類題目的鍛鍊能夠加強咱們的計算機思惟,讓計算機能更高效的爲咱們服務。
題目:兩數相加
描述:給出兩個 非空 的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式存儲的,而且它們的每一個節點只能存儲 一位 數字。若是咱們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。您能夠假設除了數字 0 以外,這兩個數都不會以 0 開頭。
示例:
相關源碼請加QQ獲取。
【感謝您能看完,若是可以幫到您,麻煩點個贊~】
更多經驗技術歡迎前來共同窗習交流: 一點課堂-爲夢想而奮鬥的在線學習平臺 http://www.yidiankt.com/
![關注公衆號,回覆「1」免費領取-【java核心知識點】]
QQ討論羣:616683098
QQ:3184402434
想要深刻學習的同窗們能夠加我QQ一塊兒學習討論~還有全套資源分享,經驗探討,等你哦!