2016-01-13 221 views
0

什麼是最佳和最有效的方式獲取最大值i,這是行數和j(它是列數),在兩個一維數組中?在java二維數組中獲取行和列的最大長度

有希望的是,對於每種情況,時間複雜度可低於O(n)。這裏沒有循環,仍然可以找到最大值j

舉例來說,如果我有這樣一個

[ 
    [18,18,19,19,20,22,22,24,25,26], 
    [1,2,3], 
    [0,0,0,0] 
] 

一個數組,那麼我想i = 3j = 10這裏作爲一個結果。

任何人都可以幫助我嗎?

回答

3

你能避免自己寫循環的數組的最大長度,但你不能避免有運行時間至少爲O(n),因爲「某人」需要循環源數組。

這裏是一個可能的方式做到這一點在Java中8:

Arrays.stream(arr).map(row -> row.length).max(Integer::compare).get(); 

這將返回一個 「行」 的最大長度在你的二維數組:

另一個版本,避免使用Comparator,因此可能會更容易閱讀:

Arrays.stream(arr).mapToInt(row -> row.length).max().getAsInt(); 

arr應該是您的源數組。

編輯:舊版本使用.max(Integer::max),這是錯誤的,並導致錯誤的結果。有關說明,請參閱this answer

+1

這是一個非常短暫和富有表現力的解決方案,我喜歡它。你知道如何從有問題的數組中創建一個parallelStream嗎? – RookieGuy

+0

@RookieGuy你可以嘗試'Arrays.stream(i).parallel()....'。 – Tom

+0

謝謝,我環顧了一下,\t \t'Arrays.asList(array).parallelStream()'也是一個沒有太多開銷的選項。 – RookieGuy

1

您的i是行數,它只是2-D數組的length(假設您在此計數中包含空行/空行)。

然而,最大行長度j將需要迭代所有行以找到具有最大值arr[i].length的行i

0

你可以試試這個方法:循環陣列上,發現這是該數組

byte[][] arrs = new byte[3][]; 
int maxLength = 0; 
for (byte[] array : arrs) { 
    if (maxLength < array.length) { 
     maxLength = array.length; 
    } 
} 
2

假設你的數組不包含空值,你可以寫這樣的事情:

private static final Comparator<int[]> lengthComparator = new Comparator<int[]>() { 
    @Override 
    public int compare(int[] o1, int[] o2) { 
     return o1.length - o2.length; 
    } 
}; 

@Test 
public void soArrayMaxLength() { 

    int[][] array = new int[][] { 
     {18,18,19,19,20, 22, 22, 24, 25,26}, 
     {1,2,3}, 
     {0,0,0,0} 
    }; 

    int i = array.length; 

    Optional<int[]> longestArray = 
      Arrays.stream(array) 
      .max(lengthComparator); 

    int j = longestArray.isPresent() ? longestArray.get().length : 0; 

    System.out.println(String.format("i=%d j=%d", i, j)); 
} 

如果你碰巧創建陣列並行流,而不是,你可以這樣進一步加快。

另一種選擇是按照長度對數組進行排序,快速排序的平均複雜度通常爲O(n * log(n)),因此這不會更快;

int i = array.length; 
    Arrays.parallelSort(array, lengthComparator); 

    int j = array[i-1].length; 

    System.out.println(String.format("i=%d j=%d", i, j)); 
+0

實際上並行搜索最長的數組; '可選 longestArray = Arrays.asList(array).parallelStream().max(lengthComparator);' – RookieGuy

1
  1. 總是會有一個循環,即使循環會在使用Java 8流解決方案隱含的。
  2. 獲取最大列數的複雜度爲O(N),其中N是行數。
  3. 使用流的隱式循環可能效率低於使用for的顯式循環。

下面是一個使用for循環

int max = o; 
for (int i = 0; i < array.length; i++) { 
    max = Math.max(max, array[i].length); 
} 

這工作在邊緣情況下array.length == 0一個整潔的解決方案,但如果array或任何array[i]null你會得到一個NullPointerException。 (你可以修改代碼,以便對,但如果不是預期的空值,一個NPE可能是一個更好的結果。)


1 - 從理論上說,你可以展開環路所有病例array.length從0到Integer.MAX_VALUE,你不需要循環。但是,代碼不會在任何已知的Java編譯器上編譯,因爲它會超過字節代碼段上的JVM限制等。由於各種原因,演出會很糟糕。