2012-03-19 23 views
4
  • 鑑於4個陣列可以包含正數和負數的數目。
  • 找到所有可能的集合與來自每個陣列的一個號碼(即,每個組將包含4個數字)的4個數字,使得總和是零。
+0

你可以蠻力,但這很慢。只是一個初步的想法 – Kevin 2012-03-19 16:58:42

+2

這是[類似的問題的答案](http://stackoverflow.com/a/8926458/1009831),它顯示瞭如何在O(n^2 * log(n))中解決這個問題,或者甚至在O(n^2)時間。 – 2012-03-19 17:16:34

+0

Python蠻力:'sum(不是sum(tup)for itertools.product(* arrays)中的tup)' – katrielalex 2012-03-19 17:17:44

回答

1

阿德里安只是沒有想到足夠遠:-)

遍歷陣列1和2以及所有款項添加到地圖。

現在從其他2個數組中找到所有組合,這些組合在地圖上從數組1和2中獲得的數字相加。它非常簡單。讓我知道你是否需要僞代碼。

O(n^2)運行時間

+0

解決方案是對的,但複雜性不是。你使用那個神奇的地圖是什麼讓O(1)訪問? – ElKamina 2012-03-19 17:41:05

+1

@ElKamina哈希表。訪問取決於密鑰的長度(在本例中是一個整數),而不是散列的大小。即使是像'bool big [maxsum]'這樣的數組就足夠了。但承認,我只是複製了Adrians的答案並交換了一些數字。 – hirschhornsalz 2012-03-19 18:44:14

+0

哈希表從不保證O(1),除非您可以承受額外的超級O(n)空間。閱讀維基百科關於基於散列結構的文章。散列表的最壞情況複雜度是O(n),但如果使用散列樹,則可以將其降至O(logn)。 – ElKamina 2012-03-19 20:57:23

1

強制的方法:注:我沒有測試過這

public void setsOfZero(int[] one,int[] two,int[] three,int[] four) 
    { 
     List<IntegerSet> setsOfIntegers = new ArrayList<IntegerSet>(); 
     for(int i =0;i < one.length ; i++) 
     { 
      for(int k = 0; k < two.length; k++) 
      { 
       for(int j = 0; j<three.length; j++) 
       { 
        for(int l = 0;l< four.length; l++) 
        { 
         if((one[i]+ two[k] + three[j] + four[l])==0) 
         { 
          IntegerSet intSet = new IntegerSet(); 
          intSet.one = one[i]; 
          intSet.two = two[k]; 
          intSet.three = three[j]; 
          intSet.four = four[l]; 

          setsOfIntegers.add(intSet); 
         } 
        } 
       } 
      } 
     } 
    } 

IntegerSet類

public class IntegerSet{ 
    public int one =0; 
    public int two =0; 
    public int three =0; 
    public int four =0; 
} 
+0

這是O(n4)解決方案....必須有一些優雅的解決方案....尋找 – ManojGumber 2012-03-19 17:15:07

+0

i,j,k,l的有趣排序。你如何用100個陣列來做到這一點? – 2012-04-09 07:24:15

2

遍歷數組1,所有的元素添加到地圖。

從其他3個陣列

現在找到其表,其中從陣列1.拿到這是非常簡單的地圖添加到一個號的所有組合。讓我知道你是否需要僞代碼。 O(n^3)運行時間

更好的解決方案是將數組2和2進行組合並對它們進行求和。你可以把它推廣到n個數組(其中n是偶數)。您正在構建一個樹形結構,其中每個節點都是一個數組。葉子是最初給定的數組,然後是一級,另外還有2個數組(從葉子開始),依此類推。 nlogn runtime,其中n是數組的平均大小。 (每個元素@position我[在陣列]您建立一個樹)

編輯: 剛一說明(由於歷史原因)
我記得我曾經有過類似的問題。我所做的是仍然使用這種二叉樹方法,但是我在樹的每個階段計算了組合。我把2個數組合併成一個大小爲n^2的大數組。然後在下一個階段新陣列的大小是n^4等等。當我剩下兩個數組時,我映射了一個數組。然後只檢查另一個數組中的元素是否在地圖中。

+0

+1對於一個好主意:我偷了你的答案,修改它,並張貼它作爲我自己;-) – hirschhornsalz 2012-03-19 17:20:20

+0

你的想法很美 – ManojGumber 2012-03-19 17:25:20

2

如果你想找到所有的人,沒有辦法做到在O(N^4),因爲可以有很多套。

如果你想不過算來,這可以在爲O(n^2日誌n)和O(N^2)空間由相遇中間人招解決。

我們稱之爲陣列A,B,C,D。我們創建了兩個陣列X和Y

for a in A: 
    for b in B: 
     X.append(a + b) 
用於Y

同樣的事情C和D.你排序X和Y(在爲O(n^2 log n))。然後你這樣做:

i = 0 
j = size(Y) - 1 
count = 0 
while i < size(X) and j >= 0: 
    if X[i] + Y[j] == 0: 
     ii = 1 
     jj = 1 
     while X[i] == X[i + 1]: 
      ii++ 
      i++ 
     while Y[j] == Y[j - 1]: 
      jj++ 
      j-- 
     count += ii * jj 
    if X[i] + Y[j] > 0: j-- 
    if X[i] + Y[j] < 0: i++ 
Output count 
1

先取兩個數組(A,B)並用成對的和創建一個新的數組(E)。對成對和數組(E)進行排序。對於其餘兩個數組(C,D)中的每一對數字,檢查它們的恭維是否存在於成對和數組(E)中。

複雜度:爲O(n^2的log(n))

+0

我認爲你的意思是O(n^2 log n) – aelguindy 2012-03-19 17:22:34

+0

它的複雜性是O(n2 * log(n)) – ManojGumber 2012-03-19 17:24:28

+0

@aelguindy是的。 – ElKamina 2012-03-19 17:39:55