【LeetCode】01 Two Sum與HashMap
阿新 • • 發佈:2018-11-21
給定一個整數陣列和一個目標值,找出陣列中和為目標值的兩個數。
你可以假設每個輸入只對應一種答案,且同樣的元素不能被重複利用。
示例:
給定 nums = [2, 7, 11, 15], target = 9
因為 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
解法1:暴力求解
class Solution { public int[] twoSum(int[] nums, int target) { for (int i = 0;i < nums.length;i++){ for (int j = i + 1;j < nums.length;j++){ if (nums[i] + nums[j] == target){ return new int[]{i,j}; } } } throw new IllegalArgumentException("No two sum solution"); } }
解法2:利用HashMap
- 解法1的問題是,我們最後要的答案是陣列的下標,而在陣列中我們只能通過下標訪問到元素。
- 如果我們只能通過下標訪問到元素,我們需要對每對可能出現的值對組合進行遍歷,那麼最後時間複雜度必然是O(n^2)
- 而如果我們可以通過元素訪問下標,遍歷一遍陣列,對於每個元素,都只需要進行一個操作:在已檢查過的元素裡查詢是否有符合條件的元素,找到則返回它的下標
換句話說,這道題的思路其實只有一種:對每一個數組中的元素,查詢某條件下的另一元素的下標
第一個迴圈,兩種方法是一致的,所以至少O(n)
陣列:我知道我有一堆元素,我不知道他們是啥。查詢的思路孜然是再遍歷一次之前的陣列元素,找到目標元素。
HashMap:我知道我有什麼元素。那麼我既然知道你要找的陣列元素大小是多少,直接檢視鍵值對裡有沒有這個鍵就好了。
class Solution { public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); int i; int complement; for (i = 0;i < nums.length;i++){ complement = target - nums[i]; if(map.containsKey(complement)){ return new int[] {map.get(complement), i}; } map.put(nums[i], i); } throw new IllegalArgumentException("!!!"); } }
這道題的目的在於,告訴我們有一種資料結構(Map)可以實現兩種結構間的一對一訪問,而其中的佼佼者,叫做HashMap(用TreeMap試驗了一下,速度比HashMap慢,時間複雜度應該是O(nlogn))