迭代数组并找到一系列数字之和

时间:2017-08-09 16:01:40

标签: javascript arrays

例如,如果我传递数字10和数组[1, 2, 4, 4],则函数应该在数组为[4,2,1,1]时函数应返回false,因为总和不在2个数字之间。

5 个答案:

答案 0 :(得分:3)

使用#some#find函数检查给定数组中任意两个数字的总和是否等于传递的参数 - 请参阅下面的演示:



function solution(num, array) {
  return array.some(function(e, i) {
    return (num - e + array.find(function(c, k) {
      return c == e && i != k
    })) == num;
  });
}


console.log(solution(8, [-1, 2, 3, 4]), solution(8, [-1, 4, 3, 4]), solution(8, [4,3,45,2,5,3]));




答案 1 :(得分:0)

我会像这样解决它,没有递归,只需循环遍历元素和下一个元素,并在找到解决方案后立即退出循环:

function solution(n, arr) {
    if (n < 0) return null;
    if (n === 0) return [];

    for (var i = 0; i < arr.length; i++) {
        var first = arr[i]; // first addend
        for (var j = i + 1; j < arr.length; j++) { // considering only next elements in the array
            if (first + arr[j] === n) {
                console.log(`found solution with ${first} and ${arr[j]}`);
                return true;
            }
        }
    }
    console.log('no solution found');
    return false;
}

console.log(solution(8, [4, 3, 45, 2, 5, 3]));
console.log(solution(8, [-1, 2, 3, 4]));

答案 2 :(得分:0)

检查两个数字之和的天真实现是一个嵌套循环,见下文:

function isSumInArray(sum, array) {
    for (let i=0; i < array.length; i++) {
        for (let j=0; j < array.length; j++) {
            if (array[i] + array[j] === sum && i !== j) {
                return true 
            }
        }
    }
    return false;
}

有更好的方法来实现这一点,但我选择它是因为我认为这是最简单的理解。你在这里经历了两次数组,如果这两个数字等于你想要的总和(并且它们在数组中不是相同的数字),那么返回true。如果所有组合都不满足此条件,则返回false。

答案 3 :(得分:0)

表示阵列中的任何两个数字

function test(array , n)
{
  for(var i=0;i<array.length;i++)
  {
    for(var j=0;j<array.length ; j++)
      if(array[i] + array[j] == n && i != j)
        return true;
  }
  return false;
}

var array = [1,2,3,4,2];
console.log(test(array , 1));
console.log(test(array , 4));

答案 4 :(得分:0)

对于每个元素,您需要与其他每个元素“进行数学运算”,看它们是否正确相加。

最简单的实现是嵌套循环O(N ^ 2)。

伪代码:

def solution(list, target)
  for each element e1 in list
    for each element e2 in list
      if e2 is e1 
        continue
      end if
      if e1 + e2 is target
        return true
      end if
    loop
  loop
  return false
end def

代码:

function solution(list, target) {
    for(let i = 0; i < list.length; i++) {
        const e1 = list[i];
        for(let j = 0; j < list.length; j++) {
            const e2 = list[j];
            if(i === j) { continue; }
            if(e1 + e2 === target) {
                return true;
            }
        }
    }
    return false;
}

console.log(solution([1,2,3,4,5], 2));

下一个最简单的解决方案是实现加法(即求和运算)是可交换的。这意味着操作数的顺序无关紧要。 1 + 2与2 + 1相同。这意味着我们不需要重新计算我们已经在外循环中访问过的数字的总和,因为随着我们前进,我们计算a + b的总和,因此根据定义覆盖b + a。但总体复杂性仍然相同:O(N ^ 2)(AFAICT)。

伪代码:

def solution(list, target)
  for each element e1 in list
    for each element e2 that is to the right of e1 in list
      if e1 + e2 is target
        return true
      end if
    loop
  loop
  return false
end def

代码:

function solution(list, target) {
    for(let i = 0; i < list.length; i++) {
        const e1 = list[i];
        for(let j = i+1; j < list.length; j++) {
            const e2 = list[j];
            if(e1 + e2 === target) {
                return true;
            }
        }
    }
    return false;
}

console.log(solution([1,2,3,4,5], 5));

更好的解决方案是将两个事实结合起来,即添加是可交换的,并且我们知道要查找什么,而不必第二次实际枚举列表。即如果a是当前元素,那么我们知道我们需要a + x = target,因此可以轻松计算x(这是差异)。通过使用O(1)查找数据结构,我们可以替换内部循环并使算法O(N)整体。

要重新陈述问题,列表中的每个元素必须与左侧的所有元素和右侧的所有元素相加。当我们使用外循环前进时,我们对所有右手元素执行求和(因为加法的可交换性)。当循环前进时,元素右侧的所有元素最终都将使用它进行测试。

为了与左边的所有元素求和,我们可以用已经看到的元素索引的哈希表替换内部循环。然后,我们可以使用a + x = targetx = target - a这一事实来检查哈希表中是否存在x

伪代码:

def solution(list, target)
  var hash <- hashtable: [integer:boolean]
  for each element in list
    if hash has sum-element
      return true
    else
      add element to hash
    endif 
  loop
end def

代码:

function solution(list, target) {
    const hash = new Set;
    for(let e of list) {
        if(hash.has(target-e)) {
            return true;
        }
        hash.add(e);
    }
    return false;
}

solution([1,2,3,4,5], 3);