1. 题目描述
运行效果
图示举例
2. 方法一:以起点、长度为研究对象,迭代更新
观察矩阵特点,填充顺序是从左至右、从上至下、从右至左、从下至上,然后再次在新的起点进行相同顺序填充。可发现每次新填充的起点沿着矩阵的主对角线。
在这一个过程中有三个重要的地方:填充起点、填充顺序和填充长度。
由此,构建仿真模拟这一过程。
- 填充起点设置对角线,每填充新的一层就往对角线下移动一个位置。
- 填充顺序按照右、下、左、上顺序进行。
- 填充长度设置一个偏移量,来控制每层填充的长度。以左闭右开([,))的填充方式进行填充。即一个方向上只填充n-1个数。
C++版本
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n));
if(n == 1) { res[0][0] = 1; return res;} // 若为1则直接返回
int startx = 0, starty = 0; // 设置每轮起点
int loop = n / 2; // 设置填充层数
int mid = n / 2; // 若n为奇数,则需要单独多填充一块
int count = 1; // 计数
int offset = 1; // 控制填充长度的偏移量
int i,j;
while(loop--){
i = startx; // 每层开始更新起点
j = starty;
for(; j < n - offset; j++){ // 向右,starty + n - offset控制填充长度
res[i][j] = count++;
}
for(; i < n - offset; i++){ // 向下
res[i][j] = count++;
}
for(; j > starty; j--){ // 向左,若偏移起点,则按顺序进行向左填充
res[i][j] = count++;
}
for(; i > startx; i--){ // 向上,若偏移起点,则按顺序进行向右填充
res[i][j] = count++;
}
startx++; // 更新起点
starty++;
offset += 1; // 更新偏移量
}
if(n % 2) res[mid][mid] = count; // 若n为奇数,则需要单独填充一块
return res;
}
};
Python版本
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
res = [[0]*n for _ in range(n)]
startx, starty, loop, mid = 0, 0, n // 2, n // 2
count = 1
for offset in range(1, loop + 1): # 每循环一层偏移量加1
for j in range(starty, n - offset): # 从左走至右
res[startx][j] = count
count += 1
for i in range(startx, n - offset): # 从上走至下
res[i][n - offset] = count
count += 1
for j in range(n - offset, starty, -1): # 从右走至左
res[n - offset][j] = count
count += 1
for i in range(n - offset, startx, -1): # 从下走左上
res[i][starty] = count
count += 1
startx += 1
starty += 1
if n % 2 != 0:
res[mid][mid] = count
return res
空间复杂度:
O
(
1
)
O(1)
O(1) 。除了返回的矩阵以外,空间复杂度是常数。
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2) 。 其中 nn 是给定的正整数。矩阵的大小是
n
×
n
n \times n
n×n,需要填入矩阵中的每个元素。
参考文章:
59.螺旋矩阵II
3. 方法二:边界收缩
记录矩阵的上、下、左、右边界标号,按照从左边界至右边界、从上边界至下边界、从右边界至左边界、从下边界至上边界的顺序。
每填充完一侧后,就将该测边界向内移一层,然后下一次填充就从该层边界的起始点开始填充。
C++版本
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n));
int top = 0, buttom = n - 1, left = 0, right = n - 1;
int count = 1, loop = n*n;
while(loop--){
for(int i = left; i <= right; i++) res[top][i] = count++; // 左边界到右边界
top++;
for(int i = top; i <= buttom; i++) res[i][right] = count++; // 上边界到下边界
right--;
for(int i = right; i >= left; i--) res[buttom][i] = count++; // 右边界到左边界
buttom--;
for(int i = buttom; i >= top; i--) res[i][left] = count++; // 下边界到上边界
left++;
}
return res;
}
};
Python版本
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
res = [[0]*n for _ in range(n)]
left, right, top, buttom = 0, n - 1, 0, n - 1
count, loop = 1, n*n
for _ in range(loop):
for i in range(left, right + 1):
res[top][i] = count
count += 1
top += 1
for i in range(top, buttom + 1):
res[i][right] = count
count += 1
right -= 1
for i in range(right, left - 1, -1):
res[buttom][i] = count
count += 1
buttom -= 1
for i in range(buttom, top - 1, -1):
res[i][left] = count
count += 1
left += 1
return res
空间复杂度:
O
(
1
)
O(1)
O(1) 。除了返回的矩阵以外,空间复杂度是常数。
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2) 。 其中 nn 是给定的正整数。矩阵的大小是
n
×
n
n \times n
n×n,需要填入矩阵中的每个元素。
参考文章:
Spiral Matrix II (模拟法,设定边界,代码简短清晰)