演算法題004 -- [給定一個整數的陣列nums,返回相加為target的兩個數字的索引值] by java
阿新 • • 發佈:2018-11-22
題目
給定一個整數的陣列nums,返回相加為target的兩個數字的索引值。
假設每次輸入都只有一個答案,並且不會使用同一個元素兩次。
舉例:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
程式碼
package algorithm4;
import java.util.HashMap;
import java.util.Map;
public class Algorithm4 {
public static void main(String[] args) {
int[] nums = {2, 5, 11, 7, 1, 9};
int[] tartgetNum = getTargetNumsByMapOptimize(nums, 10);
System.out.println(tartgetNum[0] + " ::: " + tartgetNum[1] );
}
/**方法一:
* 思路:通過兩層迴圈,拿出每一個元素,與在它之後的元素相加
* 優點:思路簡單
* 缺點:時間複雜度為 O(n^2)
*
* @param nums
* @param target
* @return
*/
public static int[] getTargetNums(int[] nums, int target) {
int[] tartgetNum = new int[2];
for(int i=0; i<nums.length -1; i++) {
//優化,只考慮i位置後面的元素,前面的元素其實已經被過濾掉了
for(int j= i+1; j<nums.length;j++) {
if((nums[i] + nums[j]) == target) {
tartgetNum[0] = i;
tartgetNum[1] = j;
return tartgetNum;
}
}
}
return tartgetNum;
}
/**方法二:
* 思路:既然在陣列中 target=a+b,
* 那麼如果利用b來記錄a的位置,
* 在遍歷的過程中,判斷元素是否被記錄過,
* 如果被記錄過,那麼就說明該元素就是我們想要找的
* 最後再通過該元素查找出a的位置。
* 優點:思路簡單,時間複雜度只有 O(2n)->O(n)
* 缺點:不易察覺的邊界條件 index != i ;
* 設有元素K1,而 target = 2 * K1,
* target = K1 + K2; K2 = K1
* 上面的假設就會導致 K2 對應的位置也就是 K1自己的位置
* 在第二次遍歷的過程中就會出現尋找到的位置是同一個
*
* @param nums
* @param target
* @return
*/
public static int[] getTargetNumsByMap(int[] nums, int target) {
int[] tartgetNum = new int[2];
HashMap<Integer, Integer> map = new HashMap<>();
//第一次迴圈
for(int i=0; i<nums.length; i++) {
int dValue = target - nums[i];
map.put(dValue, i);
}
for(int i=0; i<nums.length; i++) {
Integer index = map.get(nums[i]);
// index != i 這個邊界條件十分重要
if(index != null && index != i) {
tartgetNum[0] = index;
tartgetNum[1] = i;
return tartgetNum;
}
}
return tartgetNum;
}
/**方法三:
* 思路:在方法而的基礎上,繼續優化了時間複雜度;
* 將兩次迴圈變為一次:
* 既然設定了 target = a+b;
* 在遍歷的同時,將當前元素差值記錄下來,依然對應座標
* 那麼在之後的遍歷過程中,必然會找到對應的元素
* 此時map中儲存的value,for迴圈中的i,就是要找的index了
* 與方法二不同的是,方法二之所以會有邊界問題的存在,
* 就是因為第二次遍歷過程中,從頭開始
* 而方法三則是一路向前,絕不回頭,不會出現方法二的漏洞
* 優點:思路簡單,時間複雜度只有 O(n)
* 缺點:非要說缺點的話,也只能說犧牲空間複雜度,優化時間複雜度
* @param nums
* @param target
* @return
*/
public static int[] getTargetNumsByMapOptimize(int[] nums, int target) {
int[] result = new int[2];
Map<Integer,Integer> map = new HashMap();
for(int i=0; i<nums.length; i++){
if(map.containsKey(nums[i])){
result[0] = i;
result[1] = map.get(nums[i]);
return result;
}
map.put(target - nums[i], i);
}
return result;
}
}
思路擴充套件:
其實不一定要用map,在方法二、三中,只是引入了Map的結構,如果是一個String,也是可以做到的。