【问题标题】:Add all paired numbers in an array JavaScript在数组 JavaScript 中添加所有成对的数字
【发布时间】:2020-04-20 11:14:36
【问题描述】:

我有一个这样的数组: [20,40,60,60,20] 要求:将任意两个数字相加,如果结果可被 60 整除,则计数为 1。因此该数组应返回 3 对。 (20,40), (40,20), (60,60)。

这是我编写的代码,但它给了我 4 而不是 3

function countPlayList (array) {
  let count = 0;
  for (let i = 0; i < array.length-1; i++) {
    for (let j = 0; j < array.length-1; j++) {
      let a = array[i];
      let b = array[j];
      if (checkPlayTime(a, b) && notDuplicate(i, j)) {
        count++;
      }
    }
  }
  return count;
}

function checkPlayTime (a, b) {
  return Number.isInteger((a + b)/60);
}

function notDuplicate (x, y) {
  return x !== y ? true : false;
}

我这里有什么遗漏吗?

【问题讨论】:

  • 为什么notDuplicate()[30, 30] 应该是 1,或者不是)?这可能与您的 for 循环中的条件有关。您可能需要考虑在每个循环中必须检查哪些元素。
  • 您指定的 3 对不正确 - 实际上是 (20, 40)、(40, 20) 和 (40, 20) - 而不是 (60, 60) 会在以下情况下返回 false notDuplicate 被调用。
  • 请注意:这可以在平均 O(n) 中完成。模 60,加法逆很清楚,所以只需保持计数:arr.map(e =&gt; e % 60).reduce((p, c) =&gt; { p.n += p[(60 - c) % 60] || 0; p[c] = (p[c] || 0) + 1; return p; }, { n: 0 }).n

标签: javascript arrays duplicates nested-loops


【解决方案1】:

i+1 开始第二个循环,因为您已经在第一个循环中获取了第 i 个索引,那么您必须从 i+1 遍历到数组的长度,同时运行两个循环直到 i &lt; array.length,因为您是从index 0 开始

function countPlayList (array) {
  let count = 0;
  for (let i = 0; i < array.length; i++) {
    for (let j = i+1; j < array.length; j++) {
      let a = array[i];
      let b = array[j];
      if (checkPlayTime(a, b) && notDuplicate(i, j)) {
        count++;
      }
    }
  }
  return count;
}

function checkPlayTime (a, b) {
  return Number.isInteger((a + b)/60);
}

function notDuplicate (x, y) {
  return x !== y ? true : false;
}
console.log(countPlayList([20,40,60,60,20]))

【讨论】:

  • "运行 both 循环直到 i &lt; array.length" - 这(部分)是不必要的。
  • @Andreas 我认为这是必要的,第一个循环涵盖从` i = 0 到 arraylength - 1, second loop from j = i+1 到 arraylength - 1`,否则中间节点将丢失?
  • 为什么要查看array[array.length - 1] + array[array.length - 1]
【解决方案2】:

您的代码中有 2 个问题

  1. 您没有在整个阵列上运行,您需要运行(let i = 0; i &lt; array.length; i++)(let i = 0; i &lt;= array.length - 1; i++)
  2. 内部循环需要从外部索引 + 1 开始,因此您不会检查每个组合两次。

function countPlayList (array) {
  let count = 0;
  for (let i = 0; i < array.length - 1; i++) {
    for (let j = i + 1; j < array.length; j++) {
      let a = array[i];
      let b = array[j];
      if (checkPlayTime(a, b)) {
        count++;
      }
    }
  }
  return count;
}

function checkPlayTime (a, b) {
  return Number.isInteger((a + b)/60);
}

console.log(countPlayList([20,40,60,60,20]));

顺便说一句,不需要return x !== y ? true : false; 你可以return x !== y; 因为这个值已经是布尔值了;

【讨论】:

  • 外层必须检查直到最后一个item之前的item。
【解决方案3】:

你可以改变一些部分:

  • i + 1迭代内部直到小于数组的length
  • 使用实际对的字符串值,
  • 使用Set 来跟踪看到的配对,
  • 对求和使用不同的检查,并使用余数运算符获取余数,
  • 检查所见值,
  • 存储一个看不见的对,
  • 返回size of pairs 作为计数。

function countPlayList(array) {
    let pairs = new Set;
        
    for (let i = 0; i < array.length - 1; i++) {
        for (let j = i + 1; j < array.length; j++) {
            let a = array[i],
                b = array[j],
                pair = [a, b].join('|');
                
            if ((a + b) % 60 === 0 && !pairs.has(pair)) {
                pairs.add(pair);
            }
        }
    }
    console.log(...pairs);
    return pairs.size;
}

console.log(countPlayList([20, 40, 60, 60, 20]));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-31
    • 2014-05-23
    • 1970-01-01
    相关资源
    最近更新 更多