Javascript 给定一个数组,计算总和为60的倍数的对

Javascript 给定一个数组,计算总和为60的倍数的对,javascript,algorithm,time-complexity,big-o,Javascript,Algorithm,Time Complexity,Big O,给定一个数组,如何计算相加为60或可被60整除的对数(两个值)。注意:必须快于O(N^2) 输入:[10,50,30,90] 产出:2 推理:10+50=60,30+90=120(120可被60整除) 输入:[60,60,60] 产出:3 推理:60+60=120,60+60=120,60+60=120 下面的代码将在O(N)时间内运行,但我不知道如何处理彼此相等的对(即,如果数组中有230个值,将向计数器添加1,但如果数组中有330个值,将向计数器添加3)。我想我应该创建一个组合函数(如2C2

给定一个数组,如何计算相加为60或可被60整除的对数(两个值)。注意:必须快于O(N^2)

输入:[10,50,30,90] 产出:2 推理:10+50=60,30+90=120(120可被60整除)

输入:[60,60,60] 产出:3 推理:60+60=120,60+60=120,60+60=120

下面的代码将在O(N)时间内运行,但我不知道如何处理彼此相等的对(即,如果数组中有230个值,将向计数器添加1,但如果数组中有330个值,将向计数器添加3)。我想我应该创建一个组合函数(如2C2或3C2),但这是一个线性函数,这不就是使函数返回O(N^2)吗


更新:此解决方案为n^2,因此它无法回答原始问题

let values = [60,10,20,50,40,30, 120, 60, 10];

let count = 0;

for (let i = 0; i < values.length; i++){
    for (let j = i+1; j < values.length; j++){
        let v = values[i] + values[j];
        if (v == 60 || !(v % 60)){
            count++;
        }
    }    
}
let value=[60,10,20,50,40,30,120,60,10];
让计数=0;
for(设i=0;i
更新2:


要使其成为n+n*log(n),可以创建一个包含mod值的排序树,然后遍历每个mod值并查找60个mod值,以找到构成差异的对数。节点也可以通过存储重复次数进行优化。这能解决您的问题吗?

不需要组合。这是简单的数学

它是
n*(n-1)/2

假设您有4项
a
b
c
d

成对的将是:

  • (a、b)
  • (a、c)
  • (a、d)
  • (b、c)
  • (b、d)
  • (c、d)
对于4项,我们有4*3/2=6

#更新:

改变

count += Math.min(obj[keys], obj[60 - keys]);

考虑两个键-
12
48

  • 12
    包含元素-12,72132
  • 48
    包含元素-48108
从技术上讲,您正在为它们存储计数,即3和2。 如果你观察,我们能做的对的总数是3*2=6,而不是Math.min(3,2)

您可以在O(1)时间内计算nC2,因为nC2=n/(n)−2)!·2!= n·(n)−1) ·(n)−2)!/(n)−2)!·2!= n·(n)−1)/2!= n·(n)−1) /2

这样说,您可能需要考虑一种不同的方法:而不是有一个单独的循环来计算<代码>计数>代码>基于<代码> Obj> <代码>,您可以添加到<代码>计数>代码>您正在生成代码> Obj。这可能更直观,因为它不需要特殊情况。(由你决定。)


顺便说一句,您的
if(60-keys==keys)
测试不正确;这将检测
keys==30
的情况,但不会检测
keys==0
的情况。(您可能还需要整理一些其他错误。)

如果我们计算每个元素可以与迄今为止看到的数字形成的对,我们可以使用简单的加法,而不是管理组合数学或微妙的边缘情况

函数f(A,m){
常数rs=新数组(m+1)。填充(0);
for(设A的x){
如果(rs[(m-x%m)%m])
rs[m]+=rs[(m-x%m)%m];
rs[x%m]++;
}
返回卢比[m];
}
log(f([10,50,30,30,60]);
log(f([30,10,50,30,30,60]);

log(f([1,5,3,3,6,24,6])组合函数的线性实现是可以的,因为它相对于它所表示的元素数是线性的。因此,你在组合函数中做的工作越多,它运行的就越少。你的问题标题似乎有误导性。上面写着“找到所有的对…”,但在你的例子中,你似乎想“找到…”的对数。请澄清。记住,“obj.hasOwnProperty”也不是免费电话。随着属性数量的增加,它将变得更加昂贵。这仍然是一个二次时间算法。它是O(n*(n-1)/2)。如果数组长度为
50
项,则内部循环将运行
1225次。如果它的
100
项长,那么它将运行
4950
。是的,但它小于n^2,这是您最初的问题。不是真的。它是O(n^2)。这里有一个解释:是的,你是对的,让我看看我是否能提出一个更好的选择。添加了一个n*log(n)解决方案的想法,这适合吗?
count += Math.min(obj[keys], obj[60 - keys]);
count += obj[keys] * obj[60 - keys];