获取java二维数组中行和列的最大长度

时间:2016-01-13 07:28:05

标签: java arrays

获得最大i的最佳且有效的方法是什么,这是两个维数组中的行数和j,即列数?

希望每个案例的时间复杂度都低于O(n)。此处没有循环,仍然可以找到最大j

例如,如果我有一个像这样的数组

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

然后我希望在此处获得i = 3j = 10

愿任何人都可以帮助我吗?

5 个答案:

答案 0 :(得分:3)

你可以避免自己编写循环,但是你不能避免运行时间至少为O(n),因为“某人”需要循环源数组。

这是在Java 8中执行此操作的可能方法:

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

这将返回2d数组中“行”的最大长度:

  

10

另一个避免使用Comparator的版本因此可能更容易阅读:

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

arr应该是你的源数组。

编辑:旧版本使用.max(Integer::max),这是错误的并导致错误的结果。有关说明,请参阅this answer

答案 1 :(得分: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));

答案 2 :(得分:1)

您的i是行数,它只是2-D数组的length(假设您可以在此计数中包含空/空行)。

但是,最大行长度j需要遍历所有行才能找到具有最大i的行arr[i].length

答案 3 :(得分:1)

  1. 总会有一个循环 1 ,即使循环将隐含在使用Java 8流的解决方案中。
  2. 获取最大列数的复杂性为O(N),其中N是行数。
  3. 使用流的隐式循环可能比使用for的显式循环效率低。
  4. 这是一个使用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限制等等。由于各种原因,表现会很糟糕。

答案 4 :(得分:0)

您可以尝试这种方式:在数组上循环并找到此数组中数组的最大长度

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