螺旋矩阵II-LeetCode59 考验代码能力
力扣链接:https://leetcode.cn/problems/spiral-matrix-ii/
题目
给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
示例1:
输入:n = 3 输出:[[1,2,3],[8,9,4],[7,6,5]]
示例2:
输入:n = 1 输出:[[1]]
刚开始拿到这个题目,我想大家跟我一样,应该是很懵逼的状态,我只知道要从左到右,从上到下,但是具体怎么弄,我也不太会,属实是一看就会,一写就废。
由外向内一圈一圈这么画下去。可以发现这里的边界条件非常多,在一个循环中,如此多的边界条件,如果不按照固定规则来遍历,那就是一进循环深似海,从此offer是路人。这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,这样这一圈才能按照统一的规则画下来。
那么按照左闭右开的原则,来画一圈,大家看一下(来自代码随想录):
这里每一种颜色,代表一条边,我们遍历的长度,可以看出每一个拐角处的处理规则,拐角处让给新的一条边来继续画。这也是坚持了每条边左闭右开的原则。一些同学做这道题目之所以一直写不好,代码越写越乱。就是因为在画每一条边的时候,一会左开右闭,一会左闭右闭,一会又来左闭右开,岂能不乱。
代码如下,细品:
class Solution { public int[][] generateMatrix(int n) { int loop = 0; // 控制循环次数 int[][] res = new int[n][n]; int start = 0; // 每次循环的开始点(start, start) int count = 1; // 定义填充数字 int i, j; while (loop++ < n / 2) { // 判断边界后,loop从1开始 // 模拟上侧从左到右 for (j = start; j < n - loop; j++) { res[start][j] = count++; } // 模拟右侧从上到下 for (i = start; i < n - loop; i++) { res[i][j] = count++; } // 模拟下侧从右到左 for (; j >= loop; j--) { res[i][j] = count++; } // 模拟左侧从下到上 for (; i >= loop; i--) { res[i][j] = count++; } start++; } if (n % 2 == 1) { res[start][start] = count; } return res; } }
首先当然得先定义一个数组,然后定义一个开始点start已经一个控制循环次数变量。很显然我们循环次数不超过n/2,然后开始模拟。先从左到右,遵循左闭右开原则,给res[start][j]赋值,循环到n-loop停止,然后从上往下,给
res[i][j]赋值,此次循环的是行,接下来两个同理,和前面两步相反的方向进行即可,注意终止的条件是>=loop,最后start++(要准备下次循环开始的位置了)。最后还得判断矩阵是否是奇数大小,如果是奇数,最中间的值得填充。
这是代码随想录的解法,个人觉得比较难理解,看到了另外一种方法,更简单容易理解,代码如下:
class Solution { public int[][] generateMatrix(int n) { int[][] qq=new int[n][n]; int count=2; qq[0][0]=1; int i=0,j=0; while(count<=n*n){ while(j<n-1 && qq[i][j+1]==0) qq[i][++j]=count++; //右 while(i<n-1 && qq[i+1][j]==0) qq[++i][j]=count++; //下 while(j>0 && qq[i][j-1]==0) qq[i][--j]=count++; //左 while(i>0 && qq[i-1][j]==0) qq[--i][j]=count++; //上 } return qq; } }
怎么样,是不是简单很多了捏!!!