最近面试总会被问到在一堆数组中找两个数,他们的和等于目标值
我的一反应就写了一个双重循环。
function sum1(arr, dst){ for(let i = 0,j=arr.length;i<j;i++){ for(let k = i+1;k<j;k++){ if(dst === arr[i] + arr[k]){ return [arr[i], arr[k]] } } } return null; }
当面试官问算法复杂度,和是否可以优化时,我的一反应知道是可以优化的,但是就是不知道如何写, 当时脑袋浆糊了。。。
后面面试官问了下 hash表, hash表的原理, 然后还提示我用hash优化, 我还是没有写出来, 很尴尬。。。
看了一下网上的,顿时茅舍顿开。。。
function sum2(arr, dst){ let map = {};// key 为元素值, val 为元素索引 for(let i = 0,j=arr.length;i<j;i++){ let dif = dst - arr[i]; if(map[dif]!==undefined){ return [dif, arr[i]] } map[arr[i]] = i; } return null; }
问题又来了, 如何找出所有满足的数?
function sum3(arr, dst){ let map = {};// key 为元素值, val 为元素索引 let ret = []; for(let i = 0,j=arr.length;i<j;i++){ let dif = dst - arr[i]; if(map[dif]!==undefined){ ret.push([dif, arr[i]]) } map[arr[i]] = i; } return ret; }
问题又来了, 如果数组中有重复的呢?
function sum4(arr, dst){ arr.sort((a,b)=>a-b);// 确保元素从小到大 let map = {}; let ret = []; for(let i = 0,j=arr.length;i<j;i++){ let dif = dst - arr[i]; if(map[dif]!==undefined && map[dif][1]===false){ map[dif][1] = true; ret.push([dif, arr[i]]); } map[arr[i]] = [i, false]; } return ret; }
问题又又来了, 如果找三个数呢? 思路和找两个数一样
const threeSum = (arr, sum) => { for(let i = 0; i < arr.length; i++){ const indices = sum2(arr, sum-arr[i]); if(indices && !indices.includes(i)){ return [i, ...indices]; }; }; return -1; };