題目描述:
給定一個整數數組 nums
和一個目標值 target
,請你在該數組中找出和為目標值的那 兩個 整數,並返回他們的數組下標。
你可以假設每種輸入只會對應一個答案。但是,你不能重復利用這個數組中同樣的元素。
示例:
給定 nums = [2, 7, 11, 15], target = 9 因為 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
1.窮舉法,兩次遍歷,暴力計算。使用第1個數與后面的每個數之和判斷是否等於目標值、再用第2個數字做同樣的操作,直到完全相等,返回索引值+1:
兩個循環,時間復雜度為O(N*N)
1 var twoSum = function(nums, target) { 2 for(var i = 0; i < nums.length - 1; i++){ 3 for(var j = i + 1; j < nums.length; j++) { 4 if (nums[i] + nums[j] == target) { 5 var arr = []; 6 arr.push(i,j); 7 return arr; 8 } 9 } 10 } 11 };
2.利用indexOf, Array
的 indexOf
方法實際上是對數組再遍歷一次,寫法上有優化,但是實際時間復雜度還是O(N*N):
1 let twoSum = function(nums, target) { 2 let a, b; 3 for(let i = 0; i < nums.length; i++) { 4 b = nums.indexOf(target - nums[i]); 5 if(b > -1 && b !== i) { 6 a = i; 7 break; 8 } 9 } 10 return [a, b]; 11 };
3.使用對象索引(時間復雜度低):
創建一個對象,並給它賦值,對象的鍵值是我們想要檢索的值,對象的值是在數組中的索引。
解題思路:構造了arr{ key:value} 對象。將target-nums[i] 差值放在arr{ }對象中,並存儲其位置i。然后每次就在arr{ }對象中找有沒有對應的數即可。
1 var twoSum = function(nums, target) { 2 var arr = {}; 3 for (var i = 0; i < nums.length; i++) { 4 if (typeof(arr[nums[i]]) !== "undefined"){ 5 return [arr[nums[i]], i]; 6 } 7 arr[target - nums[i]] = i; 8 } 9 };
4.經典解題方法,排序+二分搜索
如果這個數據是有序的,那么我們很容易聯想到使用二分搜索法,可以每次判斷target-num[i]
對應的值是否在num[i+1:]
中,這個時候算法的復雜度變成了O(nlogn)
。
1 var twoSum = function getSum(arr,sum) { 2 if(arr == '' || arr.length == 0){ 3 return false; 4 } 5 // arr.sort((a,b) => { return a-b }); 如果是無序數組可先轉為有序數組再使用二分搜索法 6 var left = 0, right = arr.length -1; 7 while(left < right){ 8 if(arr[left] + arr[right] > sum){ 9 right--; 10 } 11 else if(arr[left] + arr[right] < sum){ 12 left++; 13 } 14 else{ 15 return [left,right]; 16 left++; 17 right--; 18 } 19 } 20 }
5.Hash方法,在所給數組中查找依次查找與當前值所對應的目標值是否存在,如果存在則記錄當前index值。
1 const twoSum = function(nums, target) { 2 // 用於記錄數組nums的長度 3 const length = nums.length; 4 // 實例化一個Map對象 5 let hash = new Map(); 6 let index = 0; 7 for (index = 0; index < length; index++) { 8 // 設置 hashMap 的 <key, value>,用於后面比較取值 9 hash.set(nums[index], index); 10 } 11 12 13 // 遍歷數組中的每一個數,求出另一個與其相加可以滿足條件的數的值,存儲在 @param numToFind 中 14 let numToFind; 15 for( index = 0; index < length; index++) { 16 numToFind = target - nums[index]; 17 // 查詢 hashMap 中對應的值是否有對應的index,而且不能是當前數的下標(防止出現 3 + 3 = 6,但數組nums中只有一個3這樣的情況) 18 if (hash.has(numToFind) && index !== hash.get(numToFind)) { 19 return [index, hash.get(numToFind)]; 20 } 21 } 22 };