螺旋矩阵

题目描述

给定一个包含 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进行++。

搞清楚每次怎么对数据进行维护,以及算法思路就可以,多举几个例子就很容易理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值