找到总和为目标值的所有对

时间:2018-06-17 20:52:30

标签: javascript algorithm

我一直在查看这个例子,这是一种比使用多个循环更快的匹配方式。我见过an explanation here,但这对我来说完全没有意义。

有人可以帮我解决这个问题, target - arr[i] 用于什么?

const arr = [7, 0, -4, 5, 2, 3];

const twoSum = (arr, target) => {
  let map = {}
  let results = [];
  for (let i=0; i<arr.length; i++) {
    if (map[arr[i]] !== undefined) {
      results.push([map[arr[i]], arr[i]])
    } else {
      map[target - arr[i]] = arr[i];
    }
  }
  return results;
}
console.log('twoSum = ', twoSum(arr, 5));

4 个答案:

答案 0 :(得分:1)

假设目标是t。给定数组中的值x,您想知道数组中是否存在值t - x,在这种情况下,和为t - x + x = t。

所以你通过数组来标记你在数组中看到x的事实,你在地图中标记了条目t - x。稍后当你在数组中遇到t - x时,你会检查地图中的条目t - x,如果它被填充,那么你知道你以前看过x,这意味着你有x和t - x对。我刚刚描述它的方式听起来像是通过数组的两个循环,但是你可以在一个循环中完成这两件事并且它的工作方式相同。

如果填充了地图条目,那么您之前已经看到了它的配对值,如果没有填充,则标记地图以查看您以后是否遇到该配对值。

答案 1 :(得分:1)

你甚至可以让它更快,而不存储实际值,因为你正在寻找两个值,一个是已知的,你也知道另一个。

const
    arr = [7, 0, -4, 5, 2, 3],
    twoSum = (arr, target) => {
        let map = {},
            results = [];

        for (let i = 0; i < arr.length; i++) {
            if (map[arr[i]]) {                           // straight check
                results.push([target - arr[i], arr[i]]); // take delta
                continue;
            }
            map[target - arr[i]] = true;
        }
        return results;
    };

console.log('twoSum = ', twoSum(arr, 5));

答案 2 :(得分:0)

你所链接的解释似乎有一个错误:它说的是,&#34;我们的新键/值对是5: 5。我们的哈希映射现在包含两个条目:{7: -2, 5: 5}。&#34;新密钥/值(这在代码中正确实现)是5: 0

要了解其工作原理,假设我们的数组为[2, 6, 3]且目标为5。在我们看到2后,我们想知道数组是否有其合作伙伴,它们总和为5

x + 2 = 5
x = 5 - 2
x = 3

所以我们正在寻找3。现在,JavaScript map对象允许我们在知道其键时有效地检索值。因此,我们将关键设置为3 - 这样,如果我们稍后看到3,我们就可以快速回复。请记住,我们还没有看到3。我们只是设置密钥,以便在我们看到我们已经看到其合作伙伴2时快速提醒我们。

现在我们继续沿着阵列前进。我们经过6,但地图中没有键6,因此我们将其添加到地图中并继续。当我们到达3时,我们会说,&#34;啊哈!&#34;,有3的地图提示我们,我们已经看到它的合作伙伴共同汇总到{{ 1}}。我们将结果5(当前3)和地图中存储的值推送到arr[i]密钥(3)下,即map[arr[i]]我们之前看到过。

答案 3 :(得分:0)

该算法通过检查当前处理的项目以及之前看到的项目来创建对。

因此,它需要一个内存用于之前看到的项目,这就是为什么map因素进入解决方案的原因。

让我们分析解决方案中的循环:

  for (let i=0; i<arr.length; i++) {
    if (map[arr[i]] !== undefined) {
      results.push([map[arr[i]], arr[i]])
    } else {
      map[target - arr[i]] = arr[i];
    }
  }

它等同于以下内容:

  for ( let i = 0; i < arr.length; i++ ) {

    // Any item in the array that's not in the memory
    // 1. should primarily be stored
    // 2. such that it's potential pair is stored as a key that's mapped to a value which is the item
    if ( map[ arr[ i ] ] === undefined ) {
      map[ target - arr[ i ] ] = arr[ i ];

      // Examine pairs only in iterations with odd numbered indices.
      // Why? - For the first iteration, the memory is empty...
      continue;
    }

    // this item’s pair is known, so store the pair in the result list
    results.push( [ map[ arr[ i ] ], arr[ i ] ] );
}