leecode(1)Two-Sum
從今天開始我要堅持刷leecode,就是要讓自己堅持一種學習的狀態,當然了,給自己定的目前是一週至少20道,平均每天4道(星期天的話,我覺得沒必要一定要刷,不過星期天實在沒事,刷題比打遊戲要更有意義吧)。
Two sum
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].
演練
-
先審題
輸入:系列的陣列,和一個target的結果
輸出: 從陣列中能拿到兩個數字之和等於這個target
-
第一反應
肯定是遍歷,拿一個數字和後面的數字做求和,和target對比.這就需要我們兩次遍歷,第一次遍歷去一個數字A,第2遍歷是從剩下的陣列遍歷,和數字之和等於target,這個時間複雜度是$x^{2}$.
能有麼?可以,比如哪些數字大於target直接排除,可是這個對於遍歷對於最壞的結果是沒有影響的,不過已經做到了區域性優化。
能優化到時間複雜度為 o(n)
麼?
答案是可以的?
優化
桶裝法
這個方法有點二,大家應該記得桶排序,如對100以內的數字排序:

我們也可以為我們的數字,假如說是100以內的(只是假設,那麼我們就可以,把相關數字,然後和target求差值,看下差值的桶裡有沒有。這樣遍歷只需要一次,但是空間開銷很大。
不過若是陣列中的不唯一,可能會讓大家想到了散列表,也就想到了HashMap(有些語言中叫字典)
HashMap的解法
這個是將index和數值對方放到HashMap中,key就是我們的數字,value是索引值,這樣是不是很好呢?
public int[] twoSum(int[] arr, int target) { if (arr == null || arr.length < 0 ) { return new int[]{-1,-1}; } Map<Integer, Integer> items = new HashMap<>(); for (int index = 0; index < arr.length; index++ ){ int key = arr[index]; if (items.get(target - key) != null) { return new int[]{index ,items.get(target - key)}; } else{ items.put( key, index); } } return new int[]{-1,-1}; }