【问题标题】:Get max length of row and column in java two dimensional array获取java二维数组中行列的最大长度
【发布时间】:2016-01-13 07:28:04
【问题描述】:

在二维数组中获得最大i(即行数)和j(即列数)的最佳且有效的方法是什么?

希望每种情况的时间复杂度都低于O(n)。这里没有循环,仍然可以找到最大值j。

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

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

那么我想在这里得到i = 3和j = 10结果。

谁能帮帮我?

【问题讨论】:

    标签: java arrays


    【解决方案1】:

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

    这是在 Java 8 中实现此目的的一种可能方法:

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

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

    10

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

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

    arr 应该是您的源数组。

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

    【讨论】:

    • 这是一个非常简短且富有表现力的解决方案,我喜欢它。你知道如何从相关数组中创建一个 parallelStream 吗?
    • 谢谢,我也环顾了一下,Arrays.asList(array).parallelStream() 也是一个没有太多开销的选项。
    【解决方案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));
    

    【讨论】:

    • 实际并行搜索最长的数组; Optional&lt;int[]&gt; longestArray = Arrays.asList(array).parallelStream().max(lengthComparator);
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:
      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 对字节码段等的限制。由于各种原因,性能会很糟糕。

      【讨论】:

        【解决方案5】:

        你可以试试这个方法:在数组上循环并找到这个数组中数组的最大长度

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

        【讨论】:

          猜你喜欢
          • 2011-04-29
          • 1970-01-01
          • 2018-04-19
          • 2011-11-14
          • 2012-04-20
          • 2012-07-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多