算法 - 计算O(n)中排序数组中所有相等数字对?

时间:2017-09-26 12:02:09

标签: java arrays algorithm sorting

我猜测的一个问题如下:

我们假设我们有一个数字为{1,1,1,1,2,2,4,4,4}的排序数组。

现在,鉴于我们可以清楚地看到我们在1对上有6对,1对2对和3对4对(10对)。你将如何构造一个在O(n)中找到这些对的算法?

我有一个算法来计算数组中的对,并且这样做:



Arrays.sort(array);
int counter = 0; 
for(int i = 0; i<array.length; i++) {
     for(int j = i+1; j<array.length; j++) {
          if(j!=i && array[j] == array[i]) {
	counter++;
	}
      }
}
return counter; 
&#13;
&#13;
&#13;

但这在O(N ^ 2)中运行,我猜(我是算法的新手),这是一个更好的解决方案,只使用一个for循环或多个同时获得相同的结果-loops?

我想听听你的想法!

5 个答案:

答案 0 :(得分:4)

您可以在O(N)

中执行此操作
int pairs = 0; 
int times = 1;
for (int i = 1; i < array.length; ++i) {
    if (array[i] == array[i-1]) {
        ++times;
    } else {
        pairs += times*(times-1) / 2;
        times = 1;
    }                   
}
pairs += times*(times-1) / 2;
return pairs;       

Runnable:https://ideone.com/mu65ie

对于每个不同的数字,请计算其出现次数times。不同对的数量等于选项数C(times, 2) = times*(times-1) / 2

答案 1 :(得分:2)

好的,这也是我的解决方案:

 int i = 0;
 int pairs = 0;

 while (i < array.length - 1) {
    if(array[i] == array[i + 1]) {
        pairs += 1;
        i += 2;
    } else {
        i++;
    }
 }

当找到一对时,索引增加2,这会使遍历更快一些。但无论如何,复杂性为O(n)

当然你在数组sorted之后运行它。

答案 2 :(得分:2)

秘诀是不再重申。缓存出现的数据。您可以使用缓存将其减少为O(nlogn)问题。

Pairs是非常模糊的措辞,所以将来会有更多的例子说明你不知道要找到答案的名字。您可以使用组合数学将问题减少为O(n)。

wikipedia article有点迟钝,但您正在寻找的等式接近顶部:

n! / (k! * (n - k)!)

其中!表示系数,n表示要合并的项目数量(4个1),k表示每个组合的项目数量(一对2个) )。所以用这些值代替:

4! = 24
2! = 2
(4-2)! = 2
4!/(2!2!) = 24/4 = 6

使用这个等式,它可以减少到O(n)。由于使用了阶乘并且数据集已排序,因此您可以通过缓存未来调用的阶乘调用结果来进一步提高性能。对于阶乘函数的排序输入几乎每次查找都会有缓存命中!

如果使用python 3,则可能不需要缓存,因为它使用比python 2更有效的算法计算阶乘。缓存将减少冗余,但是这可能会在非常大的值上产生良好的结果。

缓存(memoization)的一个例子:

import math

class Cache(object):
    memos = dict()

    def factorial(self, n):
         if not n in self.memos:
             self.memos[n] = math.factorial(n)
         return self.memos[n]

答案 3 :(得分:1)

怎么样:

let longMessage = `Line1
    Line2
    Line3
    Line4
    `;
bot.sendMessage(msg.chat.id, longMessage, opts);

答案 4 :(得分:0)

这是我的方法。希望它能帮助到别人:)

static int foo(int[] ar) {      
    int count = 0;
    Arrays.sort(ar);
    for(int i = 0; i<ar.length-1;i++)
    {
            if(ar[i] == ar[i+1])
            {
                count ++;
                i++;
            }
    }
    return count;

}