前言
“代码随想录”刷题记录。总结笔记均会放在“算法刷题-代码随想录”该专栏下,以下为原文的链接。
代码随想录此题链接
题目
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1
输出:[[1]]
提示:
1 <= n <= 20
1. 螺旋矩阵
思路
- 坚持循环不变量原则:就是保持遍历每个边时,都坚持:左闭右开的方式(其他的比如左开右闭也可以,每条边都坚持一种遍历方式)。
- 发现规律,就是矩阵边长为n时,n/2即为四条边被循环的次数(奇数则取整即可)
- 边长为奇数时,中间会空一个位置,值为n*n,最后加一个判断条件赋值即可。
需要的变量:
- 通过二维vector数组代表一个矩阵。
- n代表边长,mid代表矩阵的中间位置,loop代表循环的边长。(n/2获得)
- startx,starty代表起始点的横纵坐标。
- offset代表开区间与边界的距离。(比如最外层是4,开区间为4,代表到3停止,则offset=1即可)
- count 代表计数器,从1开始。
2. 本题思路分析:
同上
3. 算法实现
JAVA
public int[][] generateMatrix(int n) {
int[][] matrix = new int[n][n];
int loop = n / 2;//循环圈数
int count = 1;//赋值
int startx = 0,starty = 0;
while(loop-- > 0){
for(;starty < n - loop;starty++){
matrix[startx][starty] = count++;
}
for(;startx < n - loop;startx++){
matrix[startx][starty] = count++;
}
for(;starty >= loop;starty--){
matrix[startx][starty] = count++;
}
for(;startx >= loop;startx--){
matrix[startx][starty] = count++;
}
startx++;
starty++;
}
if(n % 2 == 1){
matrix[n / 2][n / 2] = count;
}
return matrix;
}
C++
- 代码:
#include<stdio.h>
#include<vector>
using namespace std;
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n,vector<int>(n,0));
int startx = 0,starty = 0,count = 1;
int i,j;
int offset = 1,loop = n / 2,mid = n / 2;
while(loop--){
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++;
starty++;
offset++;
}
if(n % 2 == 1){
res[mid][mid] = count;
}
return res;
}
4. 算法分析
n为数组长度
时间复杂度:O(n^2)
空间复杂度:O(n^2)
5. 算法坑点
刚开始对于整道题的解法都记不清了,但是慢慢做着做着产生思路,问题出现在对于X、Y的混乱,以及二维数组前后下标理解的混乱。
-
在第四象限,横轴代表的数为Y(列为Y轴),纵轴为X(行为X轴),
-
二维数组,第一个下标代表的是横轴值(X的值),第二个代表纵轴值(Y值)
-
螺旋矩阵的实现思想:
-
1.矩阵每轮循环,i,j作为起始坐标均要更新(+1)
-
2.矩阵要初始化。