Time:2019/4/1
Title:Two Sum
Difficulty: simple
Author:小鹿
題目一:Two Sum
Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would have exactly one solution, and you may not use the same element twice.
問題:給定一個(gè)整數(shù)數(shù)組 nums 和一個(gè)目標(biāo)值 target,請(qǐng)你在該數(shù)組中找出和為目標(biāo)值的那 兩個(gè) 整數(shù),并返回他們的數(shù)組下標(biāo)。你可以假設(shè)每種輸入只會(huì)對(duì)應(yīng)一個(gè)答案。但是,你不能重復(fù)利用這個(gè)數(shù)組中同樣的元素。
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1]
Solve:
▉ 法一:暴力破解法
算法思路:用目標(biāo)值減去數(shù)組中的某一個(gè)數(shù)值,查找差值是否在數(shù)組中存在。
/**
* 步驟:
* 1)外循環(huán):target 值要一一減去數(shù)組中的元素,記錄差值
* 2)內(nèi)循環(huán):拿著差值去數(shù)組中比較判斷是否存在
* 3)如果存在:返回兩個(gè)元素的下標(biāo)
* 4)如果不存在:繼續(xù)遍歷
*
* 性能分析:
* 1)時(shí)間復(fù)雜度分析:兩層 for 循環(huán),所以時(shí)間復(fù)雜度為 O(n^2)
* 2)空間復(fù)雜度分析:不需要額外的空間,所以空間復(fù)雜度為 O(1)
*/
var twoSum = function(nums, target) {
for(let j = 0;j < nums.length; j++){
subtract = target - nums[j];
for(let i = 0;i < nums.length; i++){
if(nums[i] == subtract && i !== j){
return [j,i]
}else{
continue;
}
}
}
return false;
};
//測(cè)試
const nums = [2,7,11,15];
console.log(twoSum(nums,26));
▉ 法二:兩遍哈希表
算法思路:先遍歷數(shù)組將下標(biāo)對(duì)應(yīng)的元素存到散列表,然后同目標(biāo)值減去的值去散列表中查看是否存在。
/**
* 步驟:
* 1)遍歷數(shù)組數(shù)據(jù),將根據(jù)下標(biāo)和元素值存放到散列表中。
* 2)目標(biāo)值減去數(shù)組元素差值并在散列表中查找。
* 3)如果存在,返回兩元素的下標(biāo)。
* 4)不存在繼續(xù)遍歷
*
* 性能分析:
* 1)時(shí)間復(fù)雜度分析:隨機(jī)訪問的時(shí)間復(fù)雜度為O(1),但是需要遍歷所有數(shù)據(jù),所以時(shí)間復(fù)雜度為 O(n)。
* 2)空間復(fù)雜度分析:需要額外的 n 大小的空間存儲(chǔ)散列表,空間復(fù)雜度為 O(n)。
*/
var twoSum = function(nums, target) {
var map = new Map();
for(let i = 0;i < nums.length; i++){
map.set(nums[i],i)
}
for (let j = 0; j < nums.length; j++) {
substra = target - nums[j];
if(map.has(substra) && map.get(substra) !== j){
return [j,map.get(substra)]
}
}
}
// 測(cè)試
const nums = [2,7,11,15];
console.log(twoSum(nums,9));
▉ 法三:一遍哈希表
算法思路:遍歷目標(biāo)值減去數(shù)組元素的差值同時(shí)判斷該值在散列表中是否存在差值,如果存在,則返回;否則將數(shù)據(jù)加入到散列表中。
/**
* 步驟:
* 1)遍歷目標(biāo)值減去數(shù)組元素的差值同時(shí)判斷該值在散列表中是否存在差值
* 2)存在該差值,返回該元素下標(biāo)
* 3)不存在,將該差值存儲(chǔ)到散列表中繼續(xù)遍歷。
*
* 性能分析:
* 1)時(shí)間復(fù)雜度分析:隨機(jī)訪問的時(shí)間復(fù)雜度為O(1),但是需要遍歷所有數(shù)據(jù),所以時(shí)間復(fù)雜度為 O(n)。
* 2)空間復(fù)雜度分析:需要額外的 n 大小的空間存儲(chǔ)散列表,空間復(fù)雜度為 O(n)。
*/
var twoSum = function(nums, target) {
var map = new Map();
for(let i = 0;i < nums.length; i++){
substra = target - nums[i];
if(map.has(substra)){
return [i,map.get(substra)]
}
map.set(nums[i],i)
}
return false;
}
// 測(cè)試
const nums = [2,7,11,15];
console.log(twoSum(nums,26));
▉ 總結(jié):
1、涉及到查找、判斷是否存在,相關(guān)的數(shù)據(jù)結(jié)構(gòu)有散列表、平衡二叉樹、二分查找、跳表、二叉查找樹。
2、使用數(shù)據(jù)結(jié)構(gòu)的時(shí)候注意適用條件。
3、注意對(duì)時(shí)間復(fù)雜度、空間復(fù)雜度的優(yōu)化策略。
LeetCode 其他題目解析,請(qǐng)關(guān)注我 Github:https://github.com/luxiangqiang/JS-LeetCode
歡迎關(guān)注我個(gè)人公眾號(hào):一個(gè)不甘平凡的碼農(nóng)