Leetcode 59. Spiral Matrix II
题目详情
Given a positive integer n, generate a square matrix filled with elements from 1 1 1 to n 2 n^2 n2 in spiral order.
Example:
Input: 3
Output:
[
[ 1, 2, 3 ],
[ 8, 9, 4 ],
[ 7, 6, 5 ]
]
题意理解
给定一个数 n n n,输出一个 n ∗ n n*n n∗n的数组,使得其由外向内逆时针的数值为 1 1 1到 n 2 n^2 n2
思路梳理
我来说一种最简单的思路,也是最直观的。如图所示:
每次沿着箭头方向依次添加数组元素,添加的元素大小为
1
1
1到
n
2
n^2
n2,即可满足题目要求。这样的解法中有很强的规律:
- 每四个箭头一组
- 箭头的变换方向为逆时针
- 每组箭头的长度以2递减
- 当箭头长度为2时停止,当箭头长度为1时,额外添加元素 n 2 n^2 n2,index为[n//2, n//2]
- 其余的细节在调试代码中发现的,比如箭头起始坐标每次横纵轴需要 + 1 +1 +1
源码展示
class Solution(object):
def generateMatrix(self, n):
"""
:type n: int
:rtype: List[List[int]]
"""
if n == 0:
return [[]]
if n == 1:
return [[1]]
N = n
res = [[0 for i in range(n)] for i in range(n)]
k = 1
index = [0, 0]
while n > 1:
for i in range(n - 1): #第一个箭头
res[index[0]][index[1] + i] = k
#print(index[0], index[1]+i, k)
k = k + 1#添加元素依次递增
index[1] = index[1] + (n - 1)#改变箭头方向的同时改变起点
for i in range(n - 1): #第二个箭头
res[index[0] + i][index[1]] = k
#print(index[0]+i, index[1], k)
k = k + 1
index[0] = index[0] + (n - 1)
for i in range(n - 1): #第三个箭头
res[index[0]][index[1] - i] = k
#print(index[0], index[1]-i, k)
k = k + 1
index[1] = index[1] - (n - 1)
for i in range(n - 1): #第四个箭头
res[index[0] - i][index[1]] = k
#print(index[0]-i, index[1], k)
k = k + 1
index[0] = index[0] - (n - 1)
index[0] = index[0] + 1#新一轮箭头起始点横坐标+1
index[1] = index[1] + 1#新一轮箭头起始点纵坐标+1
n = n - 2 #箭头长度每一轮-2
if n == 1:#当n最后为1时,额外添加元素n*n到[N//2, N//2]
res[N//2][N//2] = k
return res
代码有点零乱,但是效果还不错:
比93%的解法都快,可能是python的提交次数太少了吧
代码优化
其实每一轮的四个箭头用一个循环代替,写成四个for语句有点臃肿,下面来优化一下:
class Solution(object):
def generateMatrix(self, n):
"""
:type n: int
:rtype: List[List[int]]
"""
if n == 0:
return [[]]
if n == 1:
return [[1]]
res = [[0 for i in range(n)] for i in range(n)]
index, k, N = [0, 0], 1, n
while n > 1:
for j in range(4):#用for代替四个箭头
p = (j+1)%2#指定哪一个箭头
if j <= 1:#指定箭头的方向
mol = 1
else:
mol = -1
#print(p, mol)
for i in range(n-1):
res[index[0]][index[1]] = k
index[p] = index[p] + 1*mol
k = k + 1
n = n - 2
index[0] = index[0] + 1
index[1] = index[1] + 1
if n == 1:
res[N//2][N//2] = k
return res