例题
给你一个正整数 n
,生成一个包含 1
到 n^2
所有元素,且元素按顺时针顺序螺旋排列的 n * n
正方形矩阵 matrix
。
示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
循环不变量原则
- 本题并不涉及到什么算法,就是模拟过程。
- 写循环的过程中一定要坚持循环不变量原则,此题可以让每条边都遵循左闭右开的原则,即将拐角处让给新的一条边来继续赋值。
- 比如上述示例1中,第一条边包含元素
1
2
,第二条边包含元素3
4
,第三条边包含元素5
6
,第四条边包含元素7
8
。 - 对于
n
为奇数的情况,还需要额外处理中心元素9
:- 可以直接在循环结束后对
res[n/2][n/2]
赋值; - 也可以在定义矩阵的时候直接将其初始化为
n*n
,这样就不必处理中心元素了。
- 可以直接在循环结束后对
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
// 使用vector定义一个二维数组,初始化为n*n,不必处理中心元素
vector<vector<int>> res(n, vector<int>(n, n*n));
// 遍历的起点
int startx=0,starty=0;
// 需要控制每一条边遍历的长度,每次循环右边界收缩一位
int offset=1;
// 之所以要对ij初始化,是因为可能遇到n=1的情况
int i=startx,j=starty;
// 往res矩阵中赋的值
int count=1;
// 循环的圈数是n/2
int loop=n/2;
// 以示例1为例
while(loop)
{
// 赋值1,2
for(j=starty;j<n-offset;j++)
res[startx][j]=count++;
// 赋值3,4
for(i=startx;i<n-offset;i++)
res[i][j]=count++;
// 赋值5,6
for(;j>starty;j--)
res[i][j]=count++;
// 赋值7,8
for(;i>startx;i--)
res[i][j]=count++;
startx++;
starty++;
offset++;
loop--;
}
return res;
}
};
刷题
54. 螺旋矩阵
给你一个 m
行 n
列的矩阵 matrix
,请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
- 与例题不同的是这里的矩阵包含了长方形矩阵,此时循环的圈数应该是长和宽中的最小值再除以
2
。 - 如果长宽中最小值是奇数,就会存在需要单独处理的行或列。
- 如上述示例2的元素
6
7
。
- 如上述示例2的元素
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
// m行n列矩阵
// 注意测试集中存在[],需要对特殊情况进行处理
int m=matrix.size();
if(m==0)
return {};
int n=matrix[0].size();
if(n==0)
return {};
// 初始化一个长度为m*n的一维数组
vector<int> res(m*n);
int startx=0,starty=0;
int i=startx,j=starty;
int offset=1;
int index=0;
int loop=min(m,n)/2;
while(loop--)
{
for(j=starty;j<n-offset;j++)
res[index++]=matrix[startx][j];
for(i=startx;i<m-offset;i++)
res[index++]=matrix[i][j];
for(;j>starty;j--)
res[index++]=matrix[i][j];
for(;i>startx;i--)
res[index++]=matrix[i][j];
startx++;
starty++;
offset++;
}
if(min(m,n)%2)
{
// 在中间有多余的列
if(m>n)
{
for(i=startx;i<m-offset+1;i++)
res[index++]=matrix[i][starty];
}
// 在中间有多余的行
else
{
for(j=starty;j<n-offset+1;j++)
res[index++]=matrix[startx][j];
}
}
return res;
}
};