級別:【簡單】
/**
* 【兩數之和】 給定一個整數數組 nums和一個目標值 target,請你在該數組中找出和爲目標值的那兩個整數,並返回他們的數組下標。
*
* 你能夠假設每種輸入只會對應一個答案。可是,你不能重複利用這個數組中一樣的元素。
*
* 示例:
*
* 給定 nums = [2, 7, 11, 15], target = 9
*
* 由於 nums[0] + nums[1] = 2 + 7 = 9 因此返回 [0, 1]
*
* @Author jiawei huang
* @Since 2019年8月8日
* @Version 1.0
*/
複製代碼
一、最簡單、最粗暴的方式就是來2層for
循環,這種解法時間複雜度爲O(n^2) ,不推薦,效率低。bash
二、因爲是兩數之和等於某一個數,那麼咱們很容易就得出一個數學公式A+B=C
,咱們作一下變換,獲得A=C-B
,因爲咱們已知的是C
,顯然等式2比等式1更加容易求值,同時由於變量有兩個,小編想到的是咱們一個變量存起來,一個變量進行一次查找比較,所以就有了以下題解思路:ui
一、遍歷一遍數組,而後將每一個值與target作差存起來,同時存該數的下標;spa
二、直到找到就返回;code
三、時間複雜度爲O(n),空間複雜度也是O(n)leetcode
【解法一】get
/**
* 小編本身的解法:9ms
*
* @param nums
* @param target
* @return
*/
public static int[] twoSum(int[] nums, int target) {
int[] returnArr = null;
// 若是數組是空的,或者數組的長度爲0,直接返回
if (null == nums || nums.length == 0) {
return returnArr;
}
Map</* 差值 */Integer, /* 下標 */ Integer> dataMap = new HashMap<>();
// 既然要知道目標是第幾位,不免要知道數組的下標
for (int i = 0; i < nums.length; i++) {
Integer subNum = nums[i];
Integer key = target - subNum;
if (dataMap.containsKey(subNum)) {
// 注意,賦值操做也是耗時的
returnArr = new int[2];
returnArr[1] = i;
returnArr[0] = dataMap.get(subNum);
} else {
dataMap.put(key, i);
}
}
return returnArr;
}
複製代碼
【解法二】數學
/**
* 針對解法一,小編去除了賦值操做,時間變成6ms
*
* @param nums
* @param target
* @return
*/
public static int[] twoSumWithSetValue(int[] nums, int target) {
// 若是數組是空的,或者數組的長度爲0,直接返回
if (null == nums || nums.length == 0) {
return null;
}
Map</* 差值 */Integer, /* 下標 */ Integer> dataMap = new HashMap<>();
// 既然要知道目標是第幾位,不免要知道數組的下標
for (int i = 0; i < nums.length; i++) {
Integer subNum = nums[i];
Integer key = target - subNum;
if (dataMap.containsKey(subNum)) {
return new int[] { dataMap.get(subNum), i };
}
dataMap.put(key, i);
}
return null;
}
複製代碼
【解法三】string
// leetcode大神解法,這解法牛,1ms,但小編沒看懂,主要有下面幾個疑問,麻煩留言區討論。
public int[] twoSumOneMs(int[] nums, int target) {
int indexArrayMax = 2047;
int[] indexArrays = new int[indexArrayMax + 1];
int diff = 0;
for (int i = 0; i < nums.length; i++) {
diff = target - nums[i];
if (indexArrays[diff & indexArrayMax] != 0) {
return new int[] { indexArrays[diff & indexArrayMax] - 1, i };
}
indexArrays[nums[i] & indexArrayMax] = i + 1;
}
throw new IllegalArgumentException("No two sum value");
}
複製代碼
這解法牛,耗時僅1ms,但小編沒看懂,主要有下面2個疑問,麻煩留言區討論。it
&
的數據indexArrayMax
要選擇成20470111 1111 1111
而不是其餘值?