DailyCodingProblem,在数组中找到匹配给定值的对

Max*_*aug 6 javascript

我对编码相当陌生,并被列入每日编码问题邮件列表并得到了这个问题:

给定一个数字列表和一个数字 k,返回列表中的任意两个数字加起来是否为 k。

我的解决方案(经过一些 stackoverflow 挖掘后)看起来像这样;

function problemOne_Solve()
{
    const k = 17;
    const values = [11, 15, 3, 8, 2];
    for (i=0; i < values.length; i++) {
        if ( values.find( (sum) => { return k-values[i] === sum} ) ) return true;
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

我想知道为什么它有效。在我看来,带有 fat-arrow 函数的部分关闭了 if 语句条件逻辑内的括号。在 if 语句之后没有这样的括号,我认为这是必需的。

我还想知道如何输出总和为“k”的一对或多对,以进一步构建解决方案。例如,我希望能够在页面上显示对。

Cer*_*nce 3

.find接受一个回调,为数组中的每个项目调用该回调(或者直到找到匹配项为止)。回调的第一个参数是正在迭代的项目。如果找到匹配项(如果回调的返回值对于任何元素都是真实的),则返回.find导致真实返回值的项目。

因此,在第一次迭代中,i = 0and values[i]is会首先检查是否,然后检查是否,然后检查是否,等等。11(sum) => { return k-values[i] === sum}17 - 11 === 1117 - 11 === 1517 - 11 = 3

如果数组中的两个数字相加等于 ,则通常会满足此条件k,但该算法有错误。例如,由以下组成的数组[1]将在第一次迭代时将 1 与自身进行比较,总计为 2:

function problemOne_Solve() {
    const k = 2;
    const values = [1];
    for (i=0; i < values.length; i++) {
        if ( values.find( (sum) => { return k-values[i] === sum} ) ) return true;
    }
    return false;
}

console.log(problemOne_Solve());
Run Code Online (Sandbox Code Playgroud)

那是错的。另一个问题是.find返回找到的值。但是,如果数组是数字数组,则找到的值可能为 0,而 0 为 false。因此下面的示例应该返回,true因为两个元素之和为 0(0 和 0),但它返回false

function problemOne_Solve() {
    const k = 0;
    const values = [0, 0];
    for (i=0; i < values.length; i++) {
        if ( values.find( (sum) => { return k-values[i] === sum} ) ) return true;
    }
    return false;
}

console.log(problemOne_Solve());
Run Code Online (Sandbox Code Playgroud)

为了得到正确的结果O(n ^ 2)降低从到 的计算复杂度O(n),请对数组进行一次迭代。创建一个对象,其键是要迭代的数字,并在每次迭代时检查target - currNum该对象上是否存在键(其中target是目标总和,currNum是数组中的当前数字):

function problemOne_Solve() {
  const target = 17;
  const values = [11, 15, 3, 8, 2];
  const obj = {};
  for (const currNum of values) {
    if (obj.hasOwnProperty(target - currNum)) {
      return true;
    }
    obj[currNum] = true;
  }
  return false;
}
console.log(problemOne_Solve());
Run Code Online (Sandbox Code Playgroud)

我还想知道如何输出总和为“k”的一对或多对,以进一步构建解决方案。例如,我希望能够在页面上显示这些对。

找到匹配项时不要立即返回,而是推送到数组,然后在函数末尾返回该数组。另外,不要将对象值设置为true(或false),而是将它们设置为迄今为止找到的数字出现的次数(并在找到匹配时减少匹配数字):

function problemOne_Solve() {
  const target = 17;
  const values = [11, 15, 3, 8, 2, 17, 0, 0, 17];
  const obj = {};
  const matches = [];
  for (const currNum of values) {
    const otherNum = target - currNum;
    if (obj[otherNum]) {
      obj[otherNum]--;
      matches.push([currNum, otherNum]);
    }
    obj[currNum] = (obj[currNum] || 0) + 1;
  }
  return matches;
}
console.log(problemOne_Solve());
Run Code Online (Sandbox Code Playgroud)

而且 if 语句后面没有这样的括号,我认为这是必需的。

if当(orelse if或)之后有单个语句时不需要括号else,例如:

if (true) console.log('true');
else console.log('this will not log');
Run Code Online (Sandbox Code Playgroud)