获得最大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
。
愿任何人都可以帮助我吗?
答案 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)
O(N)
,其中N
是行数。 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限制等等。由于各种原因,表现会很糟糕。
答案 4 :(得分:0)
您可以尝试这种方式:在数组上循环并找到此数组中数组的最大长度
byte[][] arrs = new byte[3][];
int maxLength = 0;
for (byte[] array : arrs) {
if (maxLength < array.length) {
maxLength = array.length;
}
}