考虑一下单元的坐标:
. 0 1 20 A B C1 D E F2 G H I
对于任何对角线,所有元素都有一个共同点:元素坐标之和是一个常数。这是常量:
0 = 0+0 (A)1 = 1+0 (B) = 0+1 (D)2 = 2+0 (C) = 1+1 (E) = 0+2 (G)3 = 2+1 (F) = 1+2 (H)4 = 2+2 (I)
最小常数是最小坐标和0。最大常数是最大坐标和。由于每个坐标分量都可以上升到
array.length - 1,因此最大常数为
2 *(array.length - 1)。
因此,要做的事情是遍历常量。对于每个常数,迭代其坐标总和为常数的元素。这可能是最简单的方法:
for (int k = 0; k <= 2 * (array.length - 1); ++k) { for (int y = 0; y < array.length; ++y) { int x = k - y; if (x < 0 || x >= array.length) { // Coordinates are out of bounds; skip. } else { System.out.print(array[y][x]); } } System.out.println();}但是,这将最终在许多边界坐标上进行迭代,因为它总是在所有可能的
y坐标上进行迭代,即使只有一个对角线包含所有可能的
y坐标。让我们更改
y循环,使其仅访问
ycurrent所需的坐标
k。
越界坐标的一种条件是
x < 0。替换的定义
x并解决:
x < 0k - y < 0k < yy > k
因此,当时
y > k,
x将为负。因此,我们只想循环while
y <= k。
越界坐标的另一个条件是
x >= array.length。解决:
x >= array.lengthk - y >= array.lengthk - array.length >= yy <= k - array.length
所以当时
y <= k - array.length,
x将太大。因此,我们要从
y0或开始
k - array.length +1,以较大者为准。
for (int k = 0; k <= 2 * (array.length - 1); ++k) { int yMin = Math.max(0, k - array.length + 1); int yMax = Math.min(array.length - 1, k); for (int y = yMin; y <= yMax; ++y) { int x = k - y; System.out.print(array[y][x]); } System.out.println();}注意:我仅证明此代码正确。我还没有测试。



