[英]generating all unique pairs from a list of numbers, n choose 2
我有一個元素列表(比方說整數),我需要進行所有可能的2對比較。 我的方法是O(n ^ 2),我想知道是否有更快的方法。 這是我在Java中的實現。
public class Pair {
public int x, y;
public Pair(int x, int y) {
this.x = x;
this.y = y;
}
}
public List<Pair> getAllPairs(List<Integer> numbers) {
List<Pair> pairs = new ArrayList<Pair>();
int total = numbers.size();
for(int i=0; i < total; i++) {
int num1 = numbers.get(i).intValue();
for(int j=i+1; j < total; j++) {
int num2 = numbers.get(j).intValue();
pairs.add(new Pair(num1,num2));
}
}
return pairs;
}
請注意,我不允許自我配對,因此應該有((n(n + 1))/ 2)-n個可能的配對。 我目前有什么作品,但是隨着n的增加,我花了很長時間忍受不了。 有什么辦法可以將上面的O(n ^ 2)算法變成次二次方程式? 任何幫助表示贊賞。
順便說一句,我也嘗試了下面的算法,但是當我進行基准測試時,它的性能比上面的還要差。 我以為可以避免內部循環,從而可以加快速度。 下面的這種算法不應該更快嗎? 我認為這是O(n)? 如果沒有,請解釋並讓我知道。 謝謝。
public List<Pair> getAllPairs(List<Integer> numbers) {
int n = list.size();
int i = 0;
int j = i + 1;
while(true) {
int num1 = list.get(i);
int num2 = list.get(j);
pairs.add(new Pair(num1,num2));
j++;
if(j >= n) {
i++;
j = i + 1;
}
if(i >= n - 1) {
break;
}
}
}
好吧,你不能,對吧?
結果是一個包含n*(n-1)/2
元素的列表,無論這些元素是什么,僅填充此列表(用零表示)就需要O(n^2)
時間,因為n*(n-1)/2 = O(n^2)
...
您不能使其成為次二次方,因為正如您所說-輸出本身就是二次方-並且要創建它,您至少需要#elements_in_output
ops。
但是,您可以進行一些“作弊”操作以立即創建列表 :
您可以創建實現Iterable<Pair>
CombinationsGetter
類,並實現其Iterator<Pair>
。 這樣,您將能夠動態訪問元素,而無需先創建列表,這可以減少應用程序的延遲。
注意 :它將仍然是二次方! 即時生成列表的時間只會在更多操作之間分配。
編輯:另一個解決方案,它比幼稚的方法快-是多線程 。
創建幾個線程,每個線程都將得到他的數據“切片”,並生成相關對,並創建自己的部分列表。
以后-您可以使用ArrayList.addAll()
將這些不同的列表轉換為一個。
注意:盡管復雜度為O(n^2)
,但它可能會更快-因為成對創建是並行完成的,而ArrayList.addAll()
的實現要比瑣碎的一對一插入操作更有效。
EDIT2:即使它是一個“單個循環”,您的第二個代碼仍然是O(n^2)
-循環本身將重復O(n^2)
次。 看看你的變量i
。 僅當j==n
,它增加;當這樣做時,它將j
減少回i+1
。 因此,它將導致n + (n-1) + ... + 1
次迭代,這是算術級數的總和 ,並使我們回到預期的O(n^2)
。
我們無法再達到O(n ^ 2),因為我們正在嘗試創建O(n ^ 2)個不同的Pair
對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.