Given an array of integers, return indices of the two numbers such that they add up to a specific target.git
You may assume that each input would have exactly one solution, and you may not use the same element twice.github
Example:性能
Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].
這是leetcode中的一道題,看到了就想寫一下,向前輩學習一下。學習
public static int[] twoSum(int[] nums, int target) { for (int i = 0; i < nums.length; i++) { // 這裏 j = i + 1 我這邊理解的element 只能是同一個位置了 同一個數值是能夠的 for (int j = i + 1; j < nums.length; j++) { // target == nums[j] + nums[i] 與這樣寫有區別嗎? if (nums[j] == target - nums[i]) { return new int[] { i, j }; } } } //這行我是看了leetcode解答後加上的 throw new IllegalArgumentException("No two sum solution"); }
最開始想到就是所有遍歷一遍,若是找到了就返回code
int nums[] = {2,7,5,3}; int target = 9; int result[] = twoSum(nums,target); // int result[] = twoSum2(nums,target); // int result[] = twoSum3(nums,target); Arrays.stream(result).forEach(x-> System.out.print(x+" ")); System.out.println();
加個數據試試,這樣的時間複雜度O(n^2),空間複雜度O(1)。ci
那麼咱們試圖改善一下:element
public static int[] twoSum2(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); //初始化 map 中的數據 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]; //使用map containsKey來獲取有沒有匹配的值 使用了map是不能存在相同的key // 使用 nums 數據在外層循環 ,內層 map 中其實只有除去重複 key 的數據了 if (map.containsKey(complement) && map.get(complement) != i) { return new int[] { i, map.get(complement) }; } } throw new IllegalArgumentException("No two sum solution"); }
這邊使用了HashMap 來匹配數據,先要初始化一個HashMap的數據,用了空間換時間。leetcode
修改第二個For循環,雖然這樣提升了性能,時間複雜度降了下來,可是失去了很大的拓展性,這邊的要求是假設每一個輸入都有肯定的一個解,不能使用同一個數字兩次,固然題目用的element,我就不知道是同一個位置的數據,仍是同一個值,難理解,其實獲得的結果某些狀況和方法一是不同的可是若是裏面有重複數字的時候,你知道Map初始化就已經覆蓋掉了,會獲得後面的坐在位置的值。
這樣的時間複雜度O(n),空間複雜度O(n)。get
因此 對於Given nums = [2, 5,5,5, 11, 15], target = 10,這樣的數據,兩種方法獲得的結果是不同的。input
可是我看solution裏面還給了這樣寫,厲害了。
public static int[] twoSum3(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { int complement = target - nums[i]; if (map.containsKey(complement)) { return new int[] { map.get(complement), i }; } map.put(nums[i], i); } throw new IllegalArgumentException("No two sum solution"); }
前面咱們用了一個循環來初始化 map 中的數據,其實咱們還能夠延遲初始化
由於既然兩個是成對的,你來找我,仍是我找你是同樣的
可是由於是map 延遲的初始化,裏面的數據就和twoSum2的初始化的數據位置不同了,上面那個有重複數據的輸出結果會和第一種同樣。
git地址:https://github.com/woshiyexinjie/leetcode-xin
個人公衆號: