网站建设注意细节网络营销模式下品牌推广途径
题目描述
给你一个正整数n
,生成一个包含1到 n2所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例:输入3
形象展示:
返回结果: [[1,2,3],[8,9,4],[7,6,5]]
思路
解题难点
这一道题一开始写的比较混乱,思路不难就按照边界和圈圈依次赋值,原因在于难以确定每次循环的不变量是什么,例如是按照每条边一次赋值为一次大的循环,还是每一圈赋值为一次大的循环;以及每一条边赋值到哪一步停止赋值,因为可能会出现上一条边赋值3个数,下一条边赋值2个数,下下下一条边赋值一个数的情况。
解题要点
确定每次循环的不变量原则:每一条边的赋值都遵循左闭右开原则,以n=3为例,只赋值前两个数,第三个数为开,不在赋值区间内,反而是下一条边的起始(因为两条边共用一个顶点)。
这样可以保证每一条边的赋值个数是一样的,互相之间没有重叠。
面临进入下一圈赋值时,仍然是左闭右开原则,并且上一圈的赋值和下一圈的赋值互不影响。(当赋值只剩一个点时,就直接填入尾数)
需要的变量
输入的数字n
转圈轮次(不包含中心点):其与n/2有关
一个矩阵中的坐标指针,代表当前赋值的位置x和y
本轮赋值需要左闭右开的开的阈值,即以第一轮为例,n=3是1,n4的第二轮是2
代码
class Solution {
public:vector<vector<int>> generateMatrix(int n) {vector<vector<int>> result(n,vector<int>(n, 0));int num = 1;int startx = 0;int starty= 0;int edgeLengthDe=1;int randTimes = n/2; //执行轮次while(randTimes--){//这个是定义这一圈写入的起始坐标,第一轮[0][0],第二轮[1][1]int i = startx;int j = starty;//依据左闭右开原则,即同一边最左边加入,同一边最右边的作为下一条边的开头//开始从左到右填充,不包含这一行的最右一个(下一个for的起始)for(;j<n-edgeLengthDe;j++){result[i][j] = num++;}//从上到下填充,左闭右开,不包含这列最下一个(下一个for的起始)for(;i<n-edgeLengthDe;i++){result[i][j] = num++;}//从右到左填充,左闭右开。不包含这行最左一个(下一个for的起始)for(;j>starty;j--){result[i][j] = num++;}//从下到上填充。不包含这一列最上一个//(也就是[0][0]或者[1][1],这样刚好把一圈填满,下一轮次的边长不变原则再重新制定)for(;i>startx;i--){result[i][j] = num++;}//下一圈的起始位置要从类似[0][0]->[1][1]startx++;starty++;edgeLengthDe++; //下一圈的边长减少数量要加1,因为已经填过一圈了}if(n%2)//即如果n%2==1就是圈跑满了还剩下最后一个中心没填的情况{int mid = n/2;result[mid][mid]=num;}return result;}
};