跟着代码随想录顺序到这题,不会做。不知道怎么才能实现。
PS:我是用 java实现的。
题目:给你一个正整数 n ,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
总结思路为:
二维数组实现+保存结果。顺时针处理,看作处理四条边,四个for循环。
注意边界问题。
实现代码的时候犯的错:
(1)没有返回值
添加 return matrix;
(2)四周绕一圈处理值之后,n为奇数的时候最中间的值没有处理。
跳出循环后:
if(n % 2 == 1) {//奇数条件的限制
matrix[start][start] = num++;
}
这里要添加奇数条件的限制。如果没有 if 条件,当n为偶数时也会改变值。
(3)循环次数出错
分析:n=3时,绕一圈即可。n=4时,绕两圈。所以循环的次数为 n/2。
但是写while循环的时候出错了,出错的原因是,忘记 自增运算符的优先级比不等号大。
本来写的是 int loop = n/2; while(loop-- >= 0)
但是这样是不对的,因为会先判断是否大于等于0,然后进入循环,再对 loop进行减一操作。修改为while(--loop >= 0)
更直观一点,跟代码随想录中一样,int loop = 0; while (loop++ < n / 2)
这个的好处是,很直观看出循环次数和 n 之间的关系。加法相比减法也不容易出错。而且卡尔哥合并了 offset 和 loop的作用,是需要通过加法保持两者的一致性的。
(4)四个for循环都写错了
天哪,错误实在太多了。整个自己写的代码好像一句话都没对啊。。。
关键点在,顺时针处理的时候,顺序为 上->右->下->左,要清楚每一条边那个条件是不变的。比如处理 “上” 边的时候,它的纵坐标是不会变的!
(5)循环中处理边的 i j 是可以不变的
我是这么写的:
//top
for(int j=start; j<n-offset; j++) {
matrix[start][j] = num++;
}
//right
for(int i=start; i<n-offset; i++) {
matrix[i][n-offset] = num++;
}
//bottom
for(int j=n-offset; j>start; j--) {
matrix[n-offset][j] = num++;
}
//left
for(int i=n-offset; i>start; i--) {
matrix[i][start] = num++;
}
offset++;
start++;
代码随想录是这么写的:
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++;
巧妙的点
① 合并了 loop 和 offset 两个变量。
② i 和 j 可以连贯使用。
第一个for (处理上侧从左到右)执行后,j++,此时 j 为 n-offset, 然后跳出循环,这个 j 是可以复用的。因为紧接着第二个 for(处理右侧从上到下),其中的 纵坐标,也就是 j 是不变的。
我提交的代码
class Solution {
public int[][] generateMatrix(int n) {
int[][] matrix = new int[n][n];
int loop = n/2;
int start = 0 ;
int offset = 1;
int num=1;
while(--loop >= 0) {
//top
for(int j=start; j<n-offset; j++) {
matrix[start][j] = num++;
}
//right
for(int i=start; i<n-offset; i++) {
matrix[i][n-offset] = num++;
}
//bottom
for(int j=n-offset; j>start; j--) {
matrix[n-offset][j] = num++;
}
//left
for(int i=n-offset; i>start; i--) {
matrix[i][start] = num++;
}
offset++;
start++;
}
if(n % 2 != 0) {
matrix[n/2][n/2] = num++;
}
return matrix;
}
}