leetcode题目编号59.螺旋矩阵II
给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
思路
主要是模拟顺时针画矩阵的问题:
填充上行从左到右
填充右列从上到下
填充下行从右到左
填充左列从下到上
由外向内一圈一圈这么画下去。
可以发现这里的边界条件非常多,在一个循环中,如此多的边界条件,如果不按照固定规则来遍历,肯定是非常混乱的。
因此之前说到的坚持循环不变量原则就十分重要了。以坚持左闭右开为例
解法
class solution
{
public:
vector<vector<int>> generateMatrix(int n)
{
vector<vector<int>> result(n, vector<int>(n, 0)); //二维vector的初始化方式,n行n列都初始化为0
int loop = n / 2; //循环的圈数,n为3 时,只需画一圈即可,矩阵中心【1】【1】单独处理
int mid = n / 2; //中间位置
int startX = 0, startY = 0; //没循环一个圈的起始位置
int count = 1; //给矩阵中每一个空格赋值
int offset = 1; //没循环一个圈,用来控制需要遍历边的长度
int i, j;
while(loop--)
{
i = startX;
j = startY;
//模拟填充上行从左到右(左闭右开), i 不变,j 变
for (j = startY; j < startY + n - offset; j++)
{
result[i][j] = count++;
}
//模拟填充右列从上到下(左闭右开)
for (i = startX; i < startX + n - offset; i++)
{
result[i][j] = count++;
}
//模拟填充下行从右到左(左闭右开)
for (; j > startY; j--)
{
result[i][j] = count++;
}
//模拟填充左列从下到上(左闭右开)
for ( ; i > startX; i--)
{
result[i][j] = count++;
}
//每圈过后需改变每条边的遍历长度
offset += 2;
//同时每圈过后,起始位置也需加一。例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
startX++;
startY++;
}
//如果n 是奇数的话,中间位置单独处理
if (n % 2)
{
result[mid][mid] = count;
}
return result;
}
};
再次复习打算记录一下刷过的题目,同时感谢一下原文Carl 哥的分享。
大佬公众号:代码随想录
主页:原文地址