一、前言
作为代码小白(作为计算机科班出身对于一些基础c++也是掌握的,就是没有系统刷过力扣感觉算法能力不高),最近一段时间打算刷一下力扣来提升一下算法能力,在b站看到了卡哥的算法刷题合集感觉很合适我这种小白(感谢卡哥,卡哥的视频和代码是开源的都可以看到,这也是我跟随卡哥的主要原因),因此跟了几天卡哥,今天是第一次写心得,前几天实在是没有这么多的时间来写,卡哥的视频很推荐(哦对了,卡哥的账号名字叫:代码随想录)刷完应该对于算法能力有一个初步的掌握吧,接下来就记录今天的刷题过程和心得吧。
二、题目(力扣59题)
力扣链接:https://leetcode.cn/problems/spiral-matrix-ii/description/
给定一个正整数 n,生成一个包含 1 到 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3
输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
三、题解过程
大家可以看卡哥的解析过程有图有真相,很清晰(https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html)
我说一下我的代码(请各位大佬多指正(写的确实很烂,手下留情))
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0));
int quan=n/2;//循环的圈数
int offset=1;//每次向中心的偏移量,比如第一次从(0,0),第二次就是(1,1),和选择的起点有关
int starx=0,stary=0;//控制每次循环的起点
int mid=n/2;//中心位置
int num=1;
while(quan--){
int i=starx;
int j=stary;
for(j;j<n-offset;j++){//从左到右填充数字
res[i][j]=num;
num++;
}
for(i;i<n-offset;i++){//从上到下填充数字
res[i][j]=num;
num++;
}
for(j;j>starx;j--){//从右到左填充数字
res[i][j]=num;
num++;
}
for(i;i>stary;i--){//从下到上填充数字
res[i][j]=num;
num++;
}
offset++;//每次循环都向中心增加一圈
starx++;//起点也自增
stary++;
}
if((n%2)!=0){//如果是奇数矩阵则最中心的位置为(mid,mid)
res[mid][mid]=num;}
return res;
}
算法重点:
刚开始忘记设置偏移量offse以及starx、stary,直接是每次递减循环,这样主要是循环变得很复杂而且比较容易出错,这里也是整个算法的重点地方。同时注意:横向填充时应该是列变化,纵向填充时应该是行变化,而且循环的顺序不能改变因为要顺时针填充数字。
for(j;j<n-offset;j++){//从左到右填充数字
res[i][j]=num;
num++;
}
for(i;i<n-offset;i++){//从上到下填充数字
res[i][j]=num;
num++;
}
for(j;j>starx;j--){//从右到左填充数字
res[i][j]=num;
num++;
}
for(i;i>stary;i--){//从下到上填充数字
res[i][j]=num;
num++;
}
最后的这里是因为如果n为奇数(矩阵行列是奇数)的话,最中间的那个数字最后一圈循环是达到不了的,因此需要直接赋值即可。
if((n%2)!=0){//如果是奇数矩阵则最中心的位置为(mid,mid)
res[mid][mid]=num;}
四、后记
对于螺旋矩阵我觉得要点就是要注意边界条件,每一次转向的边界条件要一致这样基本就不会出错,同时可以多刷刷类似的题(卡哥也有推荐),对于c转c++的uu们,其实我觉得这也是个很好的机会来练一练c++里的STL容器,这也是c++比c好用的地方(个人感觉)。新手小白第一次写文章,有错误或者补充的地方请各位大佬批评、指正!(本文也仅仅是个人刷题过程中的一些小感受,仅用于个人记录)也欢迎各位志同道合的uu们一起学习!!!