题目描述
给定一个包含 m x n 个要素的矩阵,(m 行, n 列),写一个函数按照螺旋顺序,返回该矩阵中的所有要素。
格式:
输入依次输入两个整数 m 和 n,和一个 m x n 的整数数组,最后输出按照螺旋顺序返回的矩阵数组的元素。
样例输入
3 3
1 2 3
4 5 6
7 8 9
样例输出
1 2 3 6 9 8 7 4 5
public static void main(String[] args) {
Scanner s =new Scanner (System.in);
int m =s.nextInt();
int n=s.nextInt();
int a[][] =new int [m][n];
for(int i=0;i<m;i++) {
for(int j=0;j<n;j++) {
a[i][j]=s.nextInt();
}
}
int x=0;
int y=0;
int p=m;
int q=n;
int k=0;
while(true) {
for(int i=0;i<q;i++) {
System.out.print(a[x][y]+" ");
k++;
y++;
if(k==(m*n)) return ;
}
x++;
y--;
for(int i=1;i<p;i++) {
System.out.print(a[x][y]+" ");
k++;
x++;
if(k==(m*n)) return ;
}
x--;
y--;
q--;
p--;
for(int i=q;i>0;i--) {
System.out.print(a[x][y]+" ");
y--;
k++;
if(k==(m*n)) return ;
}
y++;
x--;
for(int i=p;i>1;i--) {
System.out.print(a[x][y]+" ");
x--;
k++;
if(k==(n*m)) return ;
}
x++;
y++;
q--;
p--;
}
}
x,y是数组的索引,p、q来限制循环的次数,k统计输出的个数,当k等于n*m时,表示数组内的数据全部输出。首先从左向右得到进行输出,然后从上到下输出,然后从右到左,然后从下到上,反复执行上述步骤,直到k==n*m时,退出循环。因为有四种方向的输出,所以要写四个for循环来表示。
对于一个3*3的数组而言,初始值x =0,y=0,p=3,q=3。经过第一个循环,i从0到2循环三次依次输出了1 2 3,此时x=0,y=3,因为输出了三个值,所以k=3。从右往左已经循环结束,开始从上到下的进行循环,此时应该从a[1][2]位置开始输出,所以要对x和y的值进行维护,让x++,y--,然后进行从上到下的输出,i从1到3循环2次,依次输出6和9,此时x=3,y=2,下次循环开始时,要从a[2][1]的位置开始,所以在对x,y进行维护,因为此时已经将3*3数组的上边和左边全部输出,所以剩下为输出的数组可以看成2*2的数组,所以此时对p和q进行维护,来减少循环的次数。接着进行从右到左的循环,从(2,1)的位置开始循环,i从2到1循环2次,依次输出8和7,此时x=2,y=-1,接下来的循环要从(1,0)的位置开始,所以继续对x和y进行维护,此时最后一个for循环执行一次,输出4,然后继续对x,y进行维护,因为经过一次while循环之后,3*3数组的最外层全部输出,所以此时只剩下1*1的数组没有输出,继续维护p和q。维护之后,继续从第一个for循环开始执行,反复操作,当k==(n*m)时,表示全部输出完毕,退出循环。
红色表示已经输出,黑色表示没有输出
执行第一个for循环之后
最上面一行全部输出,此时该执行第二个for循环,这里对x和y进行维护,然后循环
第二次for循环结束之后,可以把剩下未输出的数组看成2*2的数组,所以要对p和q进行维护,然后进行第三次for循环
第三次for循环之后,继续对x和y进行维护,开始第四次for循环
经过四次循环之后,最外层的数字已经全部输出,可以将剩下的数看成1*1的数组,维护p和q,并且维护x和y,接下来将继续执行第一个for循环,直到k==(n*m)时,结束循环。在for循环中每一次输出一个值都要对k进行++。