本博文为代码随想录的学习笔记,原文链接:代码随想录
题目
原题链接:59. 螺旋矩阵 II
给你一个正整数 n
,生成一个包含 1
到 n^2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
示例 1:
输入:n = 3 输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1 输出:[[1]]
提示:
1 <= n <= 20
思路
本题坚持循环不变量原则,模拟顺时针画矩阵的过程:
- 填充上行从左到右
- 填充右列从上到下
- 填充下列从右到左
- 填充左列从下到上
由外向内一圈一圈画下去。
可以发现这里的边界条件非常多,在一个循环中,需要按照固定规则来遍历。这里一圈我们要画四条边,每一条边坚持一致的左闭右开,这样这一拳才能按照统一的规则画下来。如下图,这里每一种颜色代表一条边,我们遍历的长度,可以看出每一个拐角处的处理规则,拐角处让给新的一条边继续画,这也是坚持了每条边左闭右开的原则。
题解
为适应机试环境,首先在Dev C++中编写程序
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> generateMatrix(int n)
{
vector<vector<int>> nums(n,vector<int>(n,0));
int loop=n/2;//需要转多少圈
int mid=n/2;//矩阵中间位置
int offset=1;//控制每一条边遍历的长度,每次循环右边界收缩一位
int count=1;//给每一个空格赋值
int startx=0,starty=0;//每一圈的起始位置
while (loop--)
{
int i=startx;
int j=starty;
for(j;j<n-offset;j++)//从左到右填充上行
{
nums[i][j]=count++;
}
for(i;i<n-offset;i++)//从上到下填充右行
{
nums[i][j]=count++;
}
for(;j>starty;j--)//从右到左填充下行
{
nums[i][j]=count++;
}
for(;i>startx;i--)//从右到左填充左行
{
nums[i][j]=count++;
}
startx++;
starty++;
offset++;
}
if(n%2)
{
nums[mid][mid]=count;
}
return nums;
}
int main()
{
int n;
cin>>n;
vector<vector<int>> res(n,vector<int>(n,0));
res=generateMatrix(n);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<res[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
在LeetCode中运行
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> nums(n, vector<int>(n, 0));
int loop = n / 2; // 需要转多少圈
int mid = n / 2; // 矩阵中间位置
int offset = 1; // 控制每一条边遍历的长度,每次循环右边界收缩一位
int count = 1; // 给每一个空格赋值
int startx = 0, starty = 0; // 每一圈的起始位置
while (loop--) {
int i = startx;
int j = starty;
for (j; j < n - offset; j++) // 从左到右填充上行
{
nums[i][j] = count++;
}
for (i; i < n - offset; i++) // 从上到下填充右行
{
nums[i][j] = count++;
}
for (; j > starty; j--) // 从右到左填充下行
{
nums[i][j] = count++;
}
for (; i > startx; i--) // 从右到左填充左行
{
nums[i][j] = count++;
}
startx++;
starty++;
offset++;
}
if (n % 2) {
nums[mid][mid] = count;
}
return nums;
}
};
复杂度分析
- 时间复杂度 O(n^2): 模拟遍历二维矩阵的时间
- 空间复杂度 O(1)