算法输出顺序如下图(长宽不固定): 程序输出效果如右图(30为进循环次数,统计用):
先上代码
package learn;
public class XieXian {
public static void main(String[] args) {
int counter=0; //遍历次数
int[][] a=
{
{9,5,1,2,4,4},
{2,5,7,4,6,8},
{7,5,1,7,5,5},
{8,5,1,2,6,5},
{5,7,3,5,1,8}
};
int n=a.length;
int m=a[0].length;
for(int i=0;i<=m+n-2;i++)
{
for(int x=0; x<=i&&(x<n)&&i-x<m ;x++)
{counter++;
System.out.print(a[x][i-x]);
System.out.print(" ");
}
for(int y=m-1; y>=0&&i-y>=0&&i-y<n&&i-y>0 ;y--)
{counter++;
System.out.print(a[i-y][y]);
System.out.print(" ");
}
System.out.println(" ");
}
System.out.println(" ");
System.out.print(counter);
}
}
最上边定义的counter是记数用的, 每次循环都+1 , 用来计算时间复杂度,
例子中的矩阵是5*6的的,共30个数, 可见输出结果counter记数30次, 时间复杂度是O(n)级别,
程序中用变量n表示行,m代表列, 由数组a确定
下边解释下算法思路:
做到二维数组的斜线输出也就是发现横纵坐标的规律 ,
我们先按输出顺序写出前几个坐标来寻找下一规律.
(0,0) (0,1) (1,0) (0,2) (1,1) (2,0) (0,3) (1,2)........
观察一下 横纵坐标的规律,
不难发现 x+y的值 为0,1,1,2,2,2,3,3,3,3...
不止如此, 大家自己划一下可以发现,
第一条斜线上有一个数 ,对应 x+y为0
第二条斜线 有两个数对应 x+y为1
第三条斜线 有三个数对应 x+y为2
...................
还有在每一条斜线中的横坐标都是从零开始 一次一加一
这样,我们找到了x+y的规律, 还有x的规律, 也就得到了横纵坐标的规律,只要控制好不要越界就好
用for循环就能很好的控制每次从0 开始 每次加1,
外层循环控制 i=x+y, 每次+1代表一条斜线画完, i不会超过宽和高的和(下标从0开始, 所以小于m+n-2)
内层循环决定每条线怎么画:
也许大家会疑惑为什么内层是两个并列的for循环, 其实两个for不会同时执行,
第一个for是我们分析的结果, x控制横坐标, 从零开始增长,但是这样存在一个问题:
从这里开始斜线不再从第一排开始, 而我们的第一内层for循环的判断从0 开始,
到这一行,我们的x再从零开始的话发现 y的坐标越界了,
我们的for循环第一次检查这个点(上图红圆)发现越界从而终止了循环
换句话说上边的分析只能让我们输出半个矩阵,下半个不输出
既然我们能输出上半个相必下半个也是类似的方法吧
我们再次观察能发现半个矩形每条线都从右边开始,和上半个的从上边开始很类似,
上半个是让x从零长, 下半个可以控制y从最大值每次-1呀,
通过分析发现x+y的值规律相同,也就是外层循环不用改,接着执行下一个for循环就可以了
这也就是一个外层for循环,两个内层for的来源,注意控制范围不要越界,
还有就是右上角开始的线既是上边的点,又是右边的点, 不控制的话会输出两遍,
所以我们第二个循环的横坐标从1开始就好了!
输出每一行是一条斜线