1. 程式人生 > >演算法題004 -- [給定一個整數的陣列nums,返回相加為target的兩個數字的索引值] by java

演算法題004 -- [給定一個整數的陣列nums,返回相加為target的兩個數字的索引值] by java

題目

給定一個整數的陣列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,也是可以做到的。