93. Spiral Matrix

Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.

For example,
Given the following matrix:

[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]

You should return [1,2,3,6,9,8,7,4,5].


题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

分析:依次找到矩阵最外面一圈还没有被找到的元素,每一圈最左上角的元素坐标是(start,start),控制找的圈数的控制条件,start*2 < rows && start*2 <cols。

不能有等号的原因是比如有4列的时候列的坐标为0,1,2,3,最多start找到1,而不能是到2。

针对找到的某圈元素进行处理的时候,分为四步:

       第一步:从左打印到右。也就是从这一圈的左上角打印到这一圈的右上角。行坐标start不变,列坐标由start到endCol;

       第二步:从上打印到下,前提是至少有两行才可以endRow > start。也就是从这一圈的右上角打印到这一圈的右下角。行坐标由start+1到endRow,列左边endCol不变;

        第三步:从右打印到左,前提是至少有两行两列才可以endRow>start && endCol > start。也就是从这一圈的右下角打印到这一圈的坐下角。行坐标endRow不变,列坐标由endCol-1到start;

        第四步:从下打印到上,前提是至少有三行两列才可以endRow > start+1 && endCol>start。也就是从这一圈的左下角打印到这一圈的左上角。行坐标由endRow-1到start+1,列坐标start不变。

       找到每一圈的初始坐标之后,进去依次判断打印的四步,满足哪一步就打印哪一步上的元素。


/**
	 * 顺时针打印给定的二维数组。 
	 * 依次找到矩阵最外面一圈还没有被找到的元素,每一圈最左上角的元素坐标是(start,start),控制找的圈数的控制条件,start*2 < rows && start*2 <cols。
	 * 不能有等号的原因是比如有4列的时候列的坐标为0,1,2,3,最多start找到1,而不能是到2.
	 * 针对找到的某圈元素进行处理的时候,分为四步:
	 * 第一步:从左打印到右。也就是从这一圈的左上角打印到这一圈的右上角。行坐标start不变,列坐标由start到endCol;
	 * 第二步:从上打印到下,前提是至少有两行才可以endRow > start。也就是从这一圈的右上角打印到这一圈的右下角。行坐标由start+1到endRow,列左边endCol不变;
	 * 第三步:从右打印到左,前提是至少有两行两列才可以endRow>start && endCol > start。也就是从这一圈的右下角打印到这一圈的坐下角。行坐标endRow不变,列坐标由endCol-1到start;
	 * 第四步:从下打印到上,前提是至少有三行两列才可以endRow > start+1 && endCol>start。也就是从这一圈的左下角打印到这一圈的左上角。行坐标由endRow-1到start+1,列坐标start不变。
	 * 
	 */
	 public List<Integer> spiralOrder(int[][] matrix) {
		 List<Integer> list = new ArrayList<Integer>();
		 int rows = matrix.length;/*记录矩阵的行数*/
		/*如果矩阵只有0行,则返回*/
		 if(rows == 0){
			 return list;
		 }
		 int cols = matrix[0].length;/*记录矩阵的列数*/
		 
		 int start = 0;
		 /*每次找出矩阵中最外面还没有被找到的那一圈元素,每一圈的开始坐标是(start,start)*/
		 while(start*2 < rows && start*2 <cols){
			 int endRow = rows-1-start; //每一圈的结束行坐标
			 int endCol = cols-1-start;
			 /*第一步打印:从左到右,行坐标start不变,列坐标由start到endCol*/
			 for(int j = start;j<=endCol;j++){
				 list.add(matrix[start][j]);
			 }
			 if(endRow > start){/*第二步打印:从上到下,行坐标由start+1到endRow-1,列左边endCol不变*/
				 for(int i = start+1;i<=endRow;i++){
					 list.add(matrix[i][endCol]);
				 }
			 }
			 if(endRow>start && endCol > start){ /*第三步打印:从右到左,行坐标endRow不变,列坐标由endCol-1到start*/
				 for(int j = endCol-1;j>=start;j--){
					 list.add(matrix[endRow][j]);
				 }
			 }
			if(endRow > start+1 && endCol>start){ /*第四步打印:从下到上,行坐标由endRow-1到start+1,列坐标start不变*/
			 for(int i = endRow-1;i>=start+1;i--){
				 list.add(matrix[i][start]);
			 }
			}
			 start++;
		 }
		 return list;
		 
	    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值