文档讲解:https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html
视频讲解:https://www.bilibili.com/video/BV1SL4y1N7mV/
看讲解前状态:不会
看讲解后状态:有思路但不会
二刷状态:
基础知识:
-
vector<vector<int>> res(n1, vector<int>(n2, 0));
这行代码的作用是创建一个大小为n1
xn2
的二维整数向量(矩阵)res
,其中每个元素都初始化为整数值0
。-
vector<vector<int>>
:这是C++标准库中的容器之一,用于存储多维数据结构。在这里,我们使用了vector
来创建一个存储整数类型的二维向量,即矩阵。 -
res
:这是你所创建的二维整数向量(矩阵)的名称。 -
n1
:表示矩阵的行数。n1
也为外层vector
的大小,即包含了n
个内层vector
的元素。
-
n2
:表示矩阵的列数。 -
vector<int>(n2, 0)
:这是内层的vector
初始化。它创建了一个包含n2
个整数元素的向量,并将每个元素初始化为 0。
-
-
这种操作通常用于初始化一个二维数组,矩阵或表格,以便在后续的计算或操作中存储数据。
题目:
https://leetcode.cn/problems/spiral-matrix-ii/
法一:
解题关键:
- 关键:四个边界循环不变量原则,边界处理区间规则要统一
- 每圈每边处理[起始-倒二](包起始,包倒二),可用左闭右开、左闭右闭表示,本质一样)
- 同二分法类似,边界坚持循环不变量原则:从头到尾坚持[左闭右开)或[左闭右闭]。
解题思路:
-
总圈数: 由题,总共应转n/2圈。
- 若n为偶数,则n/2圈后截止。
- 若n为奇数,则n/2圈后还剩最中心位置一个空处,单独填入最后一个元素即可。
- 最中间位置:(int(n/2),int(n/2))
-
每圈起始位置:
- 每一圈起始位置是变化的。所以需单独定义变量存放起始位置。
- (startX,startY),每转一圈(startX++,startY++)
- 每一圈起始位置是变化的。所以需单独定义变量存放起始位置。
-
每边起始位置
- 每圈第一边起始位置(startx,starty),
- 之后每一边:
- 左闭右开则为上一次结束位置(i,j)
- 左闭右闭则为上一次结束位置:
- 行转圈则为(i,j+/-1)
- 列转圈则为(i+/-1,j)
-
矩阵元素位置用(i,j)坐标存放。
- 行 只改变j,
- 列 只改变i,
-
当前圈数:决定每圈边长(每边终止位置)。
- 当前圈数offset从1开始
- 每边终止:例如行:(i,j)左闭右开则j<n-offset;左闭右闭则j<=n-offset-1
代码实现:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n,vector<int>(n,0));//使用vector定义一个二维数组
int startx = 0,starty=0;//定义每循环一个圈的起始位置
int loop = n/2;//一共要循环几个圈
int mid =n/2;//矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
int count = 1;//用于给矩阵中每一个空格赋值,从1开始++到n^2
int offset = 1;//当前圈数,用于控制每一条边遍历的长度(终止位置),每次循环右边界收缩一位
int i,j;//(i,j)坐标,用于遍历矩阵中每个单元格
while (loop--){
i = startx;
j = starty;
//下面模拟循环转一圈:4个for循环
//模拟填充上行从左到右(左闭右开)
for (j = starty;j<n-offset;j++){
res[startx][j] = count++;
}
for (i=startx;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+1,starty+1)
startx++;
starty++;
//offset为当前圈数,从1开始,来控制终止位置(每圈循环各边的遍历长度)
offset++;
}
//如果n为奇数的话,需要单独给矩阵最中间的空格(mid,mid)赋值n^2
if (n%2 ==1){
res[mid][mid] = count;
}
return res;
}
};
时间复杂度:O(n^2)
空间复杂度:O(1)
☹☹☹遇到的问题:
- offset初始值最开始想错了。
- vector创建二维原理不熟悉。