Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 找到两个数组元素加起来等于给定数字的更好方法_Javascript - Fatal编程技术网

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

Javascript 找到两个数组元素加起来等于给定数字的更好方法,javascript,Javascript,我写了这段代码,效果很好。然而,我认为可能有一种更干净/更好的方法来做到这一点。基本上,我必须创建一个函数,它接受两个参数(数组和sum),并返回两个元素,当它们相加时等于sum参数。有人知道如何重构代码或使其更简单吗 这是我的密码: var list=[2,6,20,4,11,30,5]; var总和=9; var myArray=[]; 函数findTwoNumbers(arr,sum){ 对于(变量i=0;i

我写了这段代码,效果很好。然而,我认为可能有一种更干净/更好的方法来做到这一点。基本上,我必须创建一个函数,它接受两个参数(数组和sum),并返回两个元素,当它们相加时等于sum参数。有人知道如何重构代码或使其更简单吗

这是我的密码:

var list=[2,6,20,4,11,30,5];
var总和=9;
var myArray=[];
函数findTwoNumbers(arr,sum){
对于(变量i=0;iconsole.log(findTwoNumbers(list,sum));//[4,5]
您可以返回数组,而无需外部数组

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 [];
}
函数findTwoNumbers(arr,sum){
对于(变量i=0;i
注意:这将只搜索满足条件的第一对,迭代路径下可能会有更多对。

您的代码是O(N^2)。您可以通过使用一个集合来减少它(尽管构建集合需要启动成本,所以您可能只会获得大型阵列的原始加速比):


另一种方法是首先对数组进行排序(O(nlog(n)),然后遍历数组,对于每个元素,找到(sum-element)之间的差异,然后对该值进行二进制搜索(O(log(n))

例如,第一个元素是2,因此您可以在排序后的数组中进行二进制搜索,查找7(9-2=7),如果找到了,则2和7是一对。一旦找到大于(sum/2)的元素,您也可以立即停止


希望这有帮助。

将数组转换为一个集合。然后遍历数组并测试集合中是否有
sum-element

我需要检查
diff==element
,以防止在向自身添加元素时返回匹配项

var list=[2,6,20,4,11,30,5];
var总和=9;
函数findTwoNumbers(arr,sum){
常数集=新集(arr);
for(设i=0;i
基本上,求和并减去数组中的第一个数字以得到余数,然后检查数组中是否存在余数,如果不存在,则转到下一个

let list=[2,6,20,4,11,30,5];
设和=9;
函数findTwoNumber(列表、总和){
for(设i=0;iconsole.log(findTwoNumbers(list,sum))
当前您的代码存在明显的问题,因为如果有多个组合来实现输入数字的和,它将返回多对数组。例如:

let list = [1, 2, 4, 1];
let sum = 5;
//would give [1, 4, 4, 1];
假设您只需要第一对,那么没有理由维护一个数组(当然也没有函数之外的数组)-只需立即返回:

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]];
}
函数findTwoNumbers(arr,sum){
for(设i=0;i
我们还可以进一步提高效率和简化。首先,循环应该忽略任何本身高于sum-1的数字(因为这是一个数字在另一个数字的帮助下仍然可以达到的最高值,而另一个数字必须是1)

既然已经是午夜了,来点无意义的语法糖怎么样

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);
}
函数findTwoNumbers(arr,sum){
设nums=arr.filter(num=>num{
返回nums.filter(num2=>num+num2==sum)[0];
}).filter(x=>x);
}


是否有多个对相加?如果没有,您可以在找到一对后立即返回,而不是继续循环。@Barmar是的,我想在找到一对后立即返回,但数字是唯一的?@Ry-是的,数字是唯一的。这是leetcode.com上的第一个问题:以及其他类似的编程问题在网站上。查看讨论部分,对各种语言的可行解决方案进行广泛分析。我一直在寻找不同于在另一个for循环中使用for循环的东西,因为我已经获得了该部分。但我正在投票。谢谢兄弟!还有其他方法,如减少重复条目,然后像@Amadan向您展示的那样,但是对于不重复的数字,它将工作相同或事件多一点。@OrelEraki:不确定“工作相同或甚至多一点”是什么意思但是它们的性能确实有很大的不同。@Ry-这意味着对于短数组,构造和添加到集合的速度会较慢,对于没有许多重复的大数组,这也会消耗内存,对于所有其他选项(很多),集合解决方案将是最好的。小心
findTwoNumbers([2,5],4)
,尽管如此。@Ry-谢谢。@progx:但是错误仍然存在,所以查找
e=>arrset.has(sum-e)&&sum-e!==e
或等效值。@progx:这不是一个非常独特的解决方案,只是将
&&sum-e!==e
添加到
find
谓词的末尾,以避免数字与自身配对。我刚刚注意到:我认为可以通过将两个指针保留在数组的任意一端并向前移动来避免二进制搜索任何一个都接近总数。注意什么?没有解决方案,所以它返回
未定义的
@Barmar谢谢兄弟。投票吧!@Ry-好的,我加了一个检查。这
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);
}