如何找到总和等于函数出现次数的数字?

时间:2018-10-21 12:04:44

标签: javascript algorithm

在输入函数中,我们不对数字数组进行排序,也不采用通过将给定数组中的数字相加而获得的数字。

有必要返回找到的第一个数字,其总和等于从函数参数获得的数字。

我几乎设法获得了所需的东西,但是由于增加了条件,我开车进入陷阱,现在我不能从零中减去负数,而又不加上另一个会否使第二个数变为正数视图,以便您可以从零中减去,然后将其转换回去。

(在第二个函数调用中,我设法在最后一个周期中从-6减去0时才将0和-6加起来)

如何从零中减去数字并减少逻辑?

function sum_pairs(ints, s){
		let arr=[];
    
    
     for(let i=0; i<ints.length; i++){
      for(let j=1; j<ints.length; j++){
       
        if(s>=0){
          if(ints[i]+ints[j] === s){
         		arr.push(ints[i], ints[j]);
         		return arr
          }
      } else{
     /*   if(ints[i] === 0 ){
           ints[j] = Math.abs(ints[j])
         } */
         if(ints[i]-ints[j] === s){
              arr.push(ints[i], ints[j]);
              return arr
           }
       }
      	
      }   		
     }
    
   
   
    
  
}

console.log(sum_pairs([1, 4, 8, 7, 3, 15], 8)) // [1,7]
console.log(sum_pairs([1, -2, 3, 0, -6, 1], -6)) // [0,-6]
console.log(sum_pairs([10, 5, 2, 3, 7, 5], 10)) // [3,7]

3 个答案:

答案 0 :(得分:1)

  

如何从零中减去数字?

  0 - someNumber
  

并减少逻辑?

1)不需要arr,只需返回数组文字即可。

2)您不需要if / else来区分阴性/阳性结果,0 + (-6)-6,因此不需要if / else。< / p>

3)您不需要元素索引,因此无需进行清理就可以进行迭代。

 function sumPairs(nums, expected) {
   for(const a of nums) {
     for(const b of nums) {
       if(a + b === expected) {
          return [a, b];
       }
     }
   }
 }

答案 1 :(得分:1)

代数

  

如何从零中减去数字并减少逻辑?

正如@Jonas Wilms提到的,在另一个数字 B 中添加负数 A 将导致从B中减去 A

let A = 1
let B = -6
A + B
// <- -5
// because (1 + -6) => (1 - 6) = -5

因此,您可以完全删除if(s>=0){

算法

您要从ints中找到总和为sum的第一对数字。

原则上,像您一样迭代ints,然后再次迭代以找到匹配的数字是正确的。

修复1:总是返回正确的对

问题

原始算法有时会返回假对。举个例子

sum_pairs([10, 5, 2, 3, 7, 1], 10))

这将错误地返回[5,5]

s = 10
i = 1
j = 1
ints[i] + ints[j] === s // true because ints[1] = 5

解决方案

确保不要在相同的数组索引处添加数字。

我们通过添加

if (j === i) continue;

function sumPairsSimple(ints, sum) {
  for (let i = 0; i < ints.length; i++) {
    for (let j = 0; j < ints.length; j++) {
      if (j === i) continue;
      if (ints[i] + ints[j] === sum) {
        return [ints[i], ints[j]]
      }
    }
  }
}
console.log(sumPairsSimple([1, 4, 8, 7, 3, 15], 8)) // [1,7]
console.log(sumPairsSimple([1, -2, 3, 0, -6, 1], -6)) // [0,-6]
console.log(sumPairsSimple([10, 5, 2, 3, 7, 1], 10)) // [3,7]

请注意,我将返回Array literal,以使代码简洁,简短且易于阅读。

修复2:优化

第二个解决方法是优化。请注意,这两个for循环都从0开始并遍历所有ints

问题

让我们假设以下呼叫:

sum_pairs([5, 4, 8, 10], 18)

这导致以下附加内容:

ints[0] + ints[1]
ints[0] + ints[2]
ints[0] + ints[3]

ints[1] + ints[0] // same as ints[0] + ints[1]
ints[1] + ints[2]
ints[1] + ints[3]

ints[2] + ints[0] // same as ints[0] + ints[2]
ints[2] + ints[1] // same as ints[1] + ints[2]
ints[2] + ints[3]

如您在上面的代码中所见,存在很多冗余。

解决方案

在这一步中,我们将删除这些冗余并赢得一些CPU周期:)

我们只检查当前元素的之后,因为我们知道我们已经在之前

ints[0] + ints[1]
ints[0] + ints[2]
ints[0] + ints[3]

ints[1] + ints[2]
ints[1] + ints[3]

ints[2] + ints[3]

这为我们节省了3个冗余计算。

在代码中,我们通过以j = i + 1开始内部循环来实现:

function sumPairsOptimized(ints, sum) {
    for(let i=0; i<ints.length; i++) {
        for(let j=i+1; j<ints.length; j++) {
            if(ints[i] + ints[j] === sum) {
                return [ints[i], ints[j]]
            }
        }
    }
}

console.log(sumPairsOptimized([1, 4, 8, 7, 3, 15], 8)) // [1,7]
console.log(sumPairsOptimized([1, -2, 3, 0, -6, 1], -6)) // [0,-6]
console.log(sumPairsOptimized([10, 5, 2, 3, 7, 1], 10)) // [3,7]

答案 2 :(得分:0)

如果您只需要第一个匹配结果,我建议结合使用Array.someArray.find

function findSummands(numbers, equalTo) {
  let summands = []
  numbers.some(lhs => numbers.find(rhs => {
    if (lhs + rhs === equalTo) {
      summands.push(lhs, rhs)
      return true
    }
    return false
  }))
  return summands
}

const test1 = findSummands([1, 4, 8, 7, 3, 15], 8)
const test2 = findSummands([1, -2, 3, 0, -6, 1], -6)
const test3 = findSummands([10, 5, 2, 3, 7, 5], 10)

console.log({test1, test2, test3})