2014-09-26 53 views
1

該賦值是創建一個方法,該方法可在int數組中找到第二大甚至int。我受限於使用任何庫中的任何方法。查找數組中第二大甚至int的有效方法

這裏是我的代碼對所有情況都適用:

public static int getSecondLargestEven(int[] ary) { 


int i; 

    aryLength = ary.length; 
    int largestEven = -1; 
    int secondLargestEven = -1; 

    for (i = 0; i < aryLength; i++) { 
     if (ary[i] % 2 == 0) { 
      if (ary[i] > largestEven) { 
       if (largestEven != -1) 
        secondLargestEven = largestEven; 

       largestEven = ary[i]; 
      } else { 
       if (ary[i] != largestEven) { 
        if (secondLargestEven == -1 || ary[i] >= secondLargestEven) { 
         secondLargestEven = ary[i]; 
        } 
       } 
      } 
     } 
    } 

此前調用methodI要求陣列有一個甚至超過其他任何方法調用。 所以,當secondLargestEven == -1時,我知道有一個重複。

是否有更高效的(少使用操作符,使用更少的循環,更少的內存分配)來實現目標?我如何改進我的代碼的邏輯?我怎樣才能提高我的整體代碼? 我不喜歡我必須分配幻數-1到secondLargestEven和最大的,因爲它們在技術上命名爲持有EVENS。使用循環將數組中的有效偶數分配給secondLargestEven和largestEven,然後繼續進行搜索是否高效?提前致謝。

+0

對於想要改進的工作代碼(運行時,資源或一般風格/體系結構),最好在[CodeReview.SE](http://codereview.stackexchange.com/)上提供。 – Ordous 2014-09-26 17:09:22

+0

您的代碼就性能而言,即使它不好,它似乎也很有效率。代碼優雅和最佳效率常常不兼容 – Joel 2014-09-26 17:10:02

+0

@Joel我認爲漸近效率在大多數情況下與優雅非常兼容。現在使用少於1個字節的東西可能會產生難看的代碼。 – Ordous 2014-09-26 17:12:20

回答

4

largestsecond變量等於-1時,您可以通過不明確檢查情況來使代碼更清晰。

只需在循環之前將這些變量設置爲Integer.MIN_VALUE--這與假設數組中有兩個額外的值先於其他所有值並且它們都具有值Integer.MIN_VALUE相同。

public static int secondLargestEven(int[] x) { 

    int largest = Integer.MIN_VALUE; 
    int second = Integer.MIN_VALUE; 

    for (int i = 0; i < x.length; i++) { 
     if (x[i] % 2 == 0) { 
      if (x[i] > largest) { 
       second = largest; 
       largest = x[i]; 
      } else if (x[i] > second) { 
       second = x[i]; 
      } 
     } 
    } 

    return second; 

} 

編輯 - 我想我會扔在那您可以通過使用循環內continue語句跳過,你有奇數的情況下刪除嵌套的一個水平,雖然有些人會認爲這比上面的代碼更難理解。

這是一個折衷 - 你在循環內使用顯式控制流(壞),但是你刪除了一個嵌套級別(好)。

public static int secondLargestEven(int[] x) { 

    int largest = Integer.MIN_VALUE; 
    int second = Integer.MIN_VALUE; 

    for (int i = 0; i < x.length; i++) { 
     if (x[i] % 2 != 0) 
      continue; 
     if (x[i] > largest) { 
      second = largest; 
      largest = x[i]; 
     } else if (x[i] > second) 
      second = x[i]; 
     } 
    } 

    return second; 

} 

只是一個有趣的思想......在Haskell中,這個功能可以寫在一行

import Data.List (sort) 

secondLargestEven = (!! 1) . reverse . sort . filter even 

,或者,如果你想成爲更有效的

import Data.List (sortBy) 
import Data.Ord (comparing) 

secondLargestEven = (!! 1) . sortBy (comparing negate) . filter even 
+0

謝謝!這絕對看起來更容易閱讀。 – qnob 2014-09-26 17:07:26

+1

如果你願意,你可以用'-2147483648'代替'Integer.MIN_VALUE',但是在我看來它會讓代碼不太清楚:) – 2014-09-26 17:08:29

+0

快速提問:將x.length賦值給某些類型爲int的變量是否更高效?每次循環迭代時我都不會調用.length()? – qnob 2014-09-26 17:11:38

0

這只是爲了好玩的實現:

public static int secondLargestEven(int[] array) { 

    Set<Integer> evenSet = new TreeSet<>(Collections.reverseOrder()); 
    for (int n : array) if (n % 2 == 0) evenSet.add(n); 
    return new ArrayList<>(evenSet).get(1); 
} 

這種方法是非常低效的(我不能看着它),而是返回第二大偶數:)

方法適用只有陣列具有第二大偶數。

相關問題