简体   繁体   English

查找两个加起来等于给定数字的数组元素的更好方法

[英]Better way to find two array elements that add up to a given number

I wrote this code that works just fine. 我写的这段代码很好用。 However I think there may be a cleaner/better way of doing this. 但是,我认为这样做可能会有更清洁/更好的方法。 Basically I have to create a function that takes 2 arguments (array and sum), and return the 2 elements that when adding them together is equals the sum parameter. 基本上,我必须创建一个接受2个参数(数组和sum)的函数,并返回将两个元素加在一起等于sum参数的2个元素。 Does anyone know how to refactor this code or make it simpler? 有谁知道如何重构该代码或使其更简单?

Here's my code: 这是我的代码:

 var list = [2, 6, 20, 4, 11, 30, 5]; var sum = 9; var myArray = []; function findTwoNumbers(arr, sum) { for (var i = 0; i < arr.length; i++) { for (var j = i + 1; j < arr.length; j++) { if (arr[i] + arr[j] === sum) { myArray.push(arr[i], arr[j]); } } } return myArray; } console.log(findTwoNumbers(list, sum)); // [4 , 5] 

Your code is O(N^2). 您的代码是O(N ^ 2)。 You can reduce it a bit by using a set (though it has a startup cost of constructing the set, so you probably get raw speedup only for large arrays): 您可以通过使用集合来减少它(尽管它具有构造集合的启动成本,因此您可能仅对大型阵列获得原始加速):

function findTwoNumbers(arr, sum) {
  const arrset = new Set(arr);
  const answer = arr.find(e => e + e !== sum && arrset.has(sum - e));
  return answer === undefined ? null : [answer, sum - answer];
}

Turn the array into a Set. 将数组变成集合。 Then iterate through the array and test whether sum - element is in the set. 然后遍历数组并测试sum - element是否在集合中。

I need to check for diff == element to prevent returning a match from adding an element to itself. 我需要检查diff == element以防止返回将元素添加到自身的匹配。

 var list = [2, 6, 20, 4, 11, 30, 5]; var sum = 9; function findTwoNumbers(arr, sum) { const set = new Set(arr); for (let i = 0; i < arr.length; i++) { let element = arr[i]; let diff = sum - element; if (diff != element && set.has(diff)) { return [element, diff]; } } } console.log(findTwoNumbers(list, sum)); // [4 , 5] console.log(findTwoNumbers([2, 5], 4)); // undefined 

You can return an array without the need of external array 您可以返回一个数组,而无需外部数组

function findTwoNumbers(arr, sum){
    for (var i = 0; i < arr.length; i++) {
        for(var j = i + 1; j < arr.length; j++){
            if(arr[i] + arr[j] === sum){
                return [arr[i] , arr[j]];
            }
        }
    }

    return [];
}

Note: This will only search for the first pair that satisfy the condition, there could be more pairs down the iteration path. 注意:这只会搜索满足条件的第一对,在迭代路径中可能会有更多对。

Another way would be to first sort the array (O(nlog(n)) then traverse the array and for each element, find the difference between (sum - element) and then do a binary search (O(log(n)) for that value. 另一种方法是先对数组(O(nlog(n))排序,然后遍历该数组,然后对每个元素求和(sum-element)之间的差,然后对它进行二进制搜索(O(log(n))那个价值。

For example, the first element is 2, so you would binary search the sorted array for 7 (9 - 2 = 7) and if you find it, then 2 and 7 are a pair. 例如,第一个元素是2,因此您将对排序后的数组进行二进制搜索以找到7(9-2 = 7),如果找到它,则2和7是一对。 You can stop short too as soon as you reach an element that is greater than (sum/2). 一旦达到大于(sum / 2)的元素,您也可以立即做空。

Hope this helps. 希望这可以帮助。

How about this: 这个怎么样:

Basically take the sum and subtract the first number in the array to get the remainder, then check if the remainder exists in the array, if not move on to the next. 基本上取总和并减去数组中的第一个数字以得到余数,然后检查数组中是否存在余数,如果不继续,则移至下一个。

 let list = [2, 6, 20, 4, 11, 30, 5]; let sum = 9; function findTwoNumbers(list, sum) { for (let i = 0; i < list.length; i++) { let n =list[i]; if (list.includes(sum - n)) { return [sum - n, n]; } } } console.log(findTwoNumbers(list, sum)) 

The obvious problem with your code currently as it will return an array of multiple pairs if there is more than one combination to achieve the sum from the input numbers. 当前,您的代码存在明显的问题,因为如果有多个组合可以从输入数字中求和,则它将返回多对数组。 So for example: 因此,例如:

let list = [1, 2, 4, 1];
let sum = 5;
//would give [1, 4, 4, 1];

Assuming you want just the first pair, there's no reason to maintain an array (and certainly not one outside the function) - just return immediately: 假设您只需要第一对,就没有理由维护一个数组(并且肯定不在函数外部)—只需立即返回:

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

There are further efficiencies and simplicities we can make. 我们可以进一步提高效率和简化性。 Firstly, the loop should ignore any number which is, in itself, higher than sum-1 (since this is the highest a number can be to still achieve the sum with the help of another number, which have to be 1.) 首先,循环应该忽略本身大于sum-1的任何数字(因为这是最高的数字,在另一个数字的帮助下仍可以求和,该数字必须为1。)

And since it's midnight, how about some pointless syntax sugar? 既然是午夜,那么一些毫无意义的语法糖又如何呢?

function findTwoNumbers(arr, sum) {
    let nums = arr.filter(num => num < sum);
    return nums.map(num => {
        return nums.filter(num2 => num + num2 == sum)[0];
    }).filter(x => x);
}

暂无
暂无

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

相关问题 在数组中找到两个数字,使它们加起来等于给定的数字 - Find two numbers in array such that they add up to a given a number 从数组中找出两个数字相加为给定数字的函数 - A function that finds two numbers out of an array that add up to the given number 有没有更好的方法将列添加到二维数组 - Is there better way to add column to two dimensional array 如何有效地找到数组中数字的索引,其中所有先前的索引加起来为给定的整数 N? - How to efficiently find the index of a number in an array at which all the previous indexes add up to a given integer N? 更好的算法,用于在数组中查找总和为提供的值的两个元素 - Better Algorithm for finding two elements in an array that sums up to the provided value 有没有更好的方法来循环遍历一个大数组来找到每个项目的数量? - Is there a better way to loop through a large array to find the number of each item? JavaScript:如何使数组中的两个元素等于任何给定数字 - JavaScript: How to get two elements in a array to equal any given number 在给定数字之间的数组中查找两个值 - Find two values in array where a given number is between JavaScript,在给定编号的数组中查找索引间隔的最佳方法 - JavaScript, best way to find the index interval in an array with given number 在数组中找到两个数字的最佳方法,它们的总和是特定数字 - best way to find two number in an array which their sum be a specific number
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM