力扣每日一题:螺旋矩阵2
每日一题:螺旋矩阵2
今天的每日一题和昨天的题目相似,昨天的题目是对于任意给定的矩阵螺旋输出结果,采用的方法是路径模拟:从起点开始向前移动,碰到墙壁或者来到已访问过的地方就顺时针旋转,一直重复m*n次。今天的题目是给定正整数n,生成一个从1到n * n螺旋排列的矩阵,思路和昨天相似,可采用路径模拟法。
方法1:路径模拟
-
题目分析:由于输出矩阵大小固定,我们首先可以声明要返回的矩阵ret,大小为n * n。由于采用路径模拟,因此需要用两个变量row和col保存当前前进到的位置,然后需要用一个变量i保存当前位置要存放的值(i同时也表示已存元素的个数)。由于在碰到已访问过的元素时要改变方向,因此要用一个n * n矩阵来表示已被访问过的元素。由于方向一共有四种,故用一个变量directionIndex保存当前行进方向 。此外,直接在循环中用directionIndex来修改变量row和col的值要用到switch,程序冗余复杂,不利于后期维护,因此使用一个数组来表示四种状态下row和col的该变量。最后根据题意,row和col根据directionIndex的指向方向来移动变化,当碰到墙壁或者来到已访问过的位置时回退同时改变方向,一直移动直到移动n * n次为止,即可完成目标。
-
代码:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
int directions[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
vector<vector<int>> ret(n, vector<int>(n));
vector<vector<bool>> visited(n, vector<bool>(n, false));
int row = 0, col = 0;
int directionIndex = 0;
for (int i = 1; i <= n * n ; i++) {
ret[row][col] = i;
visited[row][col] = true;
int nextRow = row + directions[directionIndex][0];
int nextCol = col + directions[directionIndex][1];
if (nextRow < 0 || nextRow >= n || nextCol < 0|| nextCol >= n || visited[nextRow][nextCol]) {
directionIndex = (directionIndex + 1) % 4;
}
row += directions[directionIndex][0];
col += directions[directionIndex][1];
}
return ret;
}
};
方法2:按层填入
-
题目分析:还是用路径模拟的方法实现这个题目,区别在于利用到了螺旋矩阵的一个特点:每走一个螺旋对应到输出矩阵上就是一个外圈,每次都从左上角开始螺旋,且大圈包含小圈,各个圈没有重叠部分。因此可以将题目拆分成每完成一次螺旋后去掉已填入数字。
-
变量定义:首先需要定义主操作对象——二维矩阵,该矩阵同时也是函数的返回值。然后需要用一个变量i保存每次填入的数字。对于每层模拟,用lcol(left column)和rcol分别保存矩阵左边界和右边界,用lrow,rrow保存矩阵上边界和下边界。对于每步模拟,用row,col保存当前要填入的位置。
-
常量定义:无
-
程序步骤:定义边界为矩阵边界,i为1,row和col均为0。按层数对矩阵进行循环填写数字,循环开始时先重定义row和col的数值,每个循环填写一层数字,单次循环结束时调整上下左右边界,循环结束条件为左边界大于右边界或上边界大于下边界。另外循环结束后考虑特殊情况左边界等于右边界,此时直接赋值即可。
-
代码:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> ret(n, vector<int>(n,0));
int i = 1;
int lcol = 0, rcol = n - 1;
int lrow = 0, rrow = n - 1;
int row = 0, col = 0;
while (lcol < rcol) {
row = lrow, col = lcol;
while (col < rcol) {
ret[row][col] = i;
col++;
i++;
}
while (row < rrow) {
ret[row][col] = i;
row++;
i++;
}
while (col > lcol) {
ret[row][col] = i;
col--;
i++;
}
while (row > lrow) {
ret[row][col] = i;
row--;
i++;
}
lcol += 1; rcol -= 1;
lrow += 1; rrow -= 1;
}
if (lcol == rcol) {
ret[lrow][lcol] = i;
}
return ret;
}
};

浙公网安备 33010602011771号