2012-11-25 73 views
2

我想找到的大多數陣列(數字出現的大部分時間)。 我有一個排序後的數組,並使用這些循環:錯誤在哪裏?發現大多數

for(int k = 1;k < length;k++) 
{ 
    if(arr[k-1] == arr[k]) 
    { 
     count++; 
     if(count > max) 
     { 
      max = count; 
      maxnum = arr[k-1]; 
     } 
    } else { 
     count = 0; 
    } 
} 

for(int h=0;h<length;h++) 
{ 
    for(int l=1;l<length;l++) 
    { 
     if(arr[h] == arr[l]) 
     { 
      count++; 
      if(count > max) 
      { 
       max = count; 
       maxnum = arr[h]; 
      } 
     } else count = 0; 
    } 
} 

它們similiar。當我在小陣列上嘗試它們時,一切似乎都沒有問題。但在長的運行數組N個元素0 < = N < = 500000,每個元件K 0 < = K < = 10^9他們給錯誤的答案。 這裏是錯誤http://ideone.com/y2gvnX解決方案。我知道有更好的算法可以找到大多數,但我只需要知道我的錯誤在哪裏。

我真的無法找到它:(可能喜歡幫助!

+0

在第二個中,第二個'for'循環的計數器可能應該從'h'開始,而不是'1'。 –

+1

您的第一個算法比第二個算法效率更高,而且它們不相同。第一個看起來不錯,第二個看起來不錯。 – assylias

+0

你的第一個代碼似乎是正確的。第二種方法似乎是爲未排序的數組設計的。它需要爲'h'的每個值重置'count'。 –

回答

0

你的第一個算法對我來說看起來是正確的。第二個(這是你的鏈接代碼使用的)每次循環都需要一些初始化。而且,內部循環不需要每次都從1開始;它可以在h + 1開始:

for(int h=0; h<length; h++) 
{ 
    count = 1; // for the element at arr[h] 
    for(int l=h + 1; l<length; l++) 
    { 
     if(arr[h] == arr[l]) 
     { 
      count++; 
     } 
    } 
    if(count > max) 
    { 
     max = count; 
     maxnum = arr[h]; 
    } 
} 

第一種算法是多的有序陣列更好。即使對於未排序的數組,排序數組(或其副本)也會更便宜,然後使用第一種算法而不是第二種算法。

請注意,如果存在關係(例如根據@ Rohit的評論爲數組[1, 1, 2, 2, 3]),則會查找具有最大計數的第一個值(按排序順序)。

+0

謝謝!你是對的。 – Cass

+0

@TedHopp ..您還應該引用以下情況下的錯誤結果: - [1,1,2,2,3]。它只會給'2'作爲最大數量。但它應該同時提供'1'和'2'。 –

+0

@RohitJain - 實際上它會給出2作爲'max'數量,並將給出1作爲'maxnum'。但是你是對的 - 我會澄清它會在關係中返回第一個最大值。 –

0

如果數組進行排序您的第一個算法纔有意義。

你的第二個算法只是在錯誤的地方設置計數爲零你要你進入內環路for之前,計數設置爲零。

for(int h=0;h<length;h++) 
{ 
    count = 0; 
    for(int l=0;l<length;l++) 
    { 
    if(arr[h] == arr[l]) 
    { 
    count++; 
    if(count > max) 
    { 
    max = count; 
    maxnum = arr[h]; 
    } 
    } 
    } 
} 

而且,你不需要每次都檢查count在內部循環。

max = 0; 
for(int h=0;h<length;h++) 
{ 
    count = 0; 
    for(int l=0;l<length;l++) 
    { 
    if(arr[h] == arr[l]) 
    count++; 
    } 
    if(count > max) 
    { 
    max = count; 
    maxnum = arr[h]; 
    } 
} 
+2

第一個算法對於排序數組非常有意義(相等的值將是連續的)。 –

+0

謝謝。我更新了我的答案。 –

+0

謝謝!第一個算法是正確的,但第二個沒有通過測試(我檢查http://acm.timus.ru/submit.aspx?space=1&num=1510)。 – Cass

0

的錯誤,我可以很容易地看到的是,如果所有元素都是不同的,那麼最大的末尾爲0 但是它必須是1 所以,當你在「其他」的情況下更新計數,將其更新到1而不是0,作爲一個新的元素已經被發現,其計數爲1

1

首先,你應該使用first algorithm,爲您的數組進行排序。第二種算法不必要地通過陣列兩次。

現在你first algorithm幾乎是正確的,但它有兩個問題: -

  • 第一個問題是您要設置count = 0,在其他部分, 而是應設置爲1。因爲每個元素至少有一次 。
  • 其次,你不需要每次都設置maxif。只需要 increment count,直到if-condition得到滿足,並且儘快 爲​​,請檢查current countcurrent max,並相應地重置當前的最大值。

這樣,你max不會在每次迭代檢查,但只有當不匹配被發現。

所以,你可以嘗試這樣的代碼: -

// initialize `count = 1`, and `maxnum = Integer.MIN_VALUE`. 
    int count = 1; 
    int max = 0; 
    int maxnum = Integer.MIN_VALUE; 

    for(int k = 1;k < length;k++) 
    { 
     if(arr[k-1] == arr[k]) { 
       count++; // Keep on increasing count till elements are equal 

     } else { 
      // if Condition fails, check for the current count v/s current max 

      if (max < count) { // Move this from `if` to `else` 
       max = count; 
       maxnum = arr[k - 1]; 
      } 
      count = 1; // Reset count to 1. As every value comes at least once. 
     } 
    } 

注: -

這種方法的問題是,如果兩個數字會說話 - 13,來的人數相等倍 - 這是最大,則max計數將計數3(假設3自帶1後,和maxnum將包含3並忽略1。但他們都應該考慮。

因此,基本上,您不能使用for loop並維護count來處理此問題。

更好的方法是創建一個Map<Integer, Integer>,並將每個值的計數存儲在那裏。然後sortMapvalue

+0

謝謝!我用地圖,但它需要更多的內存。否則,它會更好。 – Cass

+0

@ Will_code_4_food ..然後在這種情況下,不要存儲所有的int,count映射。只需將當前最大值存儲在int值中,並在最大值更改時對其進行更新。如果找到兩個值相同的最大值,則將它們都存儲起來。您需要使用這種方法,以確保您在所有情況下都能得到正確的結果。 –

+0

這是真的。謝謝。 – Cass