题目:
给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3
输出:
[
[ 1, 2, 3 ],
[ 8, 9, 4 ],
[ 7, 6, 5 ]
]
算法过程:
按照填充的数学规律,把这个方阵填完。可以发现这一定是一个正方形的矩阵,而且横着向右填完一行后,下一次横着向右填的那一行的行数等于上一次填的行数+1,其他运动有类似的结论,所以在代码中出现了up += 1的代码。那确定了填的行数,从哪里开始哪里结尾呢?再次以横向向右运动为例,设置left ,right的初始值为0, n -1 ,然后这2个就是边界,这2个值的是会变的,他们变的原因与横向向右运动up变的原因相同。
算法证明:
无证明,观察得到。
代码:
class Solution:
def generateMatrix(self, n):
pass
direction=0
up=left=0
down,right=n-1,n-1
matrix=[[0 for i in range(n)] for j in range(n)]
#生成器
nums=range(1,n**2+1)
item=0
#向ans里按螺旋顺序添加
while up<=down and left<=right:
if direction==0:
for i in range(left,right+1):
#up在这里表示填充的这一行的行数
matrix[up][i]=nums[item]
item+=1
up+=1
elif direction==1:
for i in range(up,down+1):
#right表示填充的这一行的列数
matrix[i][right]=nums[item]
item+=1
right-=1
elif direction==2:
for i in range(left,right+1)[::-1]:
#down表示填充的这一行的行数
matrix[down][i]=nums[item]
item+=1
down-=1
else:
for i in range(up,down+1)[::-1]:
#left表示填充这一行的列数
matrix[i][left]=nums[item]
item+=1
left+=1
direction=(direction+1)%4
return matrix
当然了这道题与上道题及其相似,答案只需稍稍修改即可,可以参考:Leetcode 054 螺旋矩阵
JAVA 代码:
public int[][] generateMatrix(int n) {
int[][] ret = new int[n][n];
int left = 0;
int right = n - 1;
int up = 0;
int down = n - 1;
int count = 1;
while (left <= right && up <= down) {
// 右
for (int j = left; j <= right; j++)
ret[up][j] = count++;
up++;
// 下
for (int j = up; j <= down; j++)
ret[j][right] = count++;
right--;
// 左
for (int j = right; j >= left; j--)
ret[down][j] = count++;
down--;
// 上
for (int j = down; j >= up; j--)
ret[j][left] = count++;
left++;
}
return ret;
}
C++
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int> > generateMatrix(int n)
{
vector< vector<int> > matrix(n, vector<int>(n));
if (n == 0)
return matrix;
int beginX = 0, endX = n - 1;
int beginY = 0, endY = n - 1;
int num = 1;
while (true)
{
for (int j = beginX; j <= endX; ++j)
matrix[beginY][j] = num++;
if (++beginY > endY)
break;
for (int i = beginY; i <= endY; ++i)
matrix[i][endX] = num++;
if (beginX > --endX)
break;
for (int j = endX; j >= beginX; --j)
matrix[endY][j] = num++;
if (beginY > --endY)
break;
for (int i = endY; i >= beginY; --i)
matrix[i][beginX] = num++;
if (++beginX > endX)
break;
}
return matrix;
}
int main()
{
vector<vector<int>> vec;
int n=3;
vec=generateMatrix(n);
vector<vector<int>>::iterator pp;
vector<int>::iterator it;
for(pp=vec.begin();pp<vec.end();pp++)
{
for (it=(*pp).begin();it<(*pp).end();it++)
{
cout<<*it<<" ";
}
cout<<endl;
}
return 0;
}
总结:按一定顺序去操作数组的时候,要善于发现操作的规律,比如这一题,观察到了开始位置的坐标,结束位置的纵坐标的话就会非常好做。