繁体   English   中英

迭代数组并找到一定范围内的数字之和

[英]Iterate array and find the sum between a range of numbers

例如,如果我通过数字10和阵列[1, 2, 4, 4]的函数应该如果阵列是[4,2,1,1]的函数应返回假,因为总和2之间不数字。

使用#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])); 

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

 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])); 

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

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。

对于数组中的任何拖数

 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)); 

对于每个元素,您需要对所有其他元素进行“数学运算”,以查看它们是否正确求和。

最简单的实现是嵌套循环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 = target ,因此x = 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); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM