算法题 螺旋矩阵Ⅰ/Ⅱ

螺旋矩阵

给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。

示例 1:

输入:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]

示例 2:

输入:
[
  [1, 2, 3, 4],
  [5, 6, 7, 8],
  [9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]

思路:分层考虑,由外到内一圈一圈解决。方向是→↓←↑,控制好边界就OK了。

代码:

public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> res = new LinkedList<Integer>();
        if(matrix.length == 0) return res;
        int m = matrix.length, n = matrix[0].length;
        // 计算圈数
        int lvl = (Math.min(m, n) + 1) / 2;
        for(int i = 0; i < lvl; i++){
            // 计算相对应的该圈最后一行
            int lastRow = m - i - 1;
            // 计算相对应的该圈最后一列
            int lastCol = n - i - 1;
            // 如果该圈第一行就是最后一行,说明只剩下一行
            if(i == lastRow){
                for(int j = i; j <= lastCol; j++){
                    res.add(matrix[i][j]);
                }
            // 如果该圈第一列就是最后一列,说明只剩下一列
            } else if(i == lastCol){
                for(int j = i; j <= lastRow; j++){
                    res.add(matrix[j][i]);
                }
            } else {
                // 第一行
                for(int j = i; j < lastCol; j++){
                    res.add(matrix[i][j]);
                }
                // 最后一列
                for(int j = i; j < lastRow; j++){
                    res.add(matrix[j][lastCol]);
                }
                // 最后一行
                for(int j = lastCol; j > i; j--){
                    res.add(matrix[lastRow][j]);
                }
                // 第一列
                for(int j = lastRow; j > i; j--){
                    res.add(matrix[j][i]);
                }
            }
        }
        return res;
    }

https://segmentfault.com/a/1190000003817711



螺旋矩阵 II

给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。

示例:

输入: 3
输出:
[
 [ 1, 2, 3 ],
 [ 8, 9, 4 ],
 [ 7, 6, 5 ]
]

思路:

比第一题简单,控制好边界按方向旋转就OK了。

代码:

public int[][] generateMatrix(int n) {
        int[][] a = new int[n][n];
		int count = 1;
		
		for(int k=0;k<n;k++){
			for(int j=k;j<n-k;j++){
				a[k][j]=count++;
			}
			for(int i=k+1;i<n-k;i++){
				a[i][n-1-k]=count++;
			}
			for(int j=n-2-k;j>=k;j--){
				a[n-1-k][j]=count++;
			}
			for(int i=n-k-2;i>k;i--){
				a[i][k]=count++;
			}
		}
		
		return a;
    }


思考:如果这题改为m行n列,该怎么改呢

public static int[][] generateMatrix(int m,int n) {
	        int[][] a = new int[m][n];
			int count = 1;
			int level = (Math.min(m,n)+1)/2;
			int lastrow = 0;
			int lastcol = 0;
			int firstrow = 0;
			int firstcol = 0;
			for(int k=0;k<level;k++){
				lastrow = m-k-1;
				lastcol = n-k-1;
				firstrow = k;
				firstcol = k;
				if(firstrow==lastrow){
					for(int i=firstcol;i<lastcol+1;i++)
						a[firstrow][i]=count++;
					return a;
				}
				if(firstcol==lastcol){
					for(int i=firstrow;i<lastrow+1;i++)
						a[i][firstrow]=count++;
					return a;
				}
				for(int col=firstcol;col<lastcol;col++)
					a[firstrow][col]=count++;
				for(int row=firstrow;row<lastrow;row++)
					a[row][lastcol]=count++;
				for(int col=lastcol;col>firstcol;col--)
					a[lastrow][col]=count++;
				for(int row=lastrow;row>firstrow;row--)
					a[row][firstcol]=count++;	
			}		
			return a;
	    }

实测效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值