本篇文章为笔者的LeetCode刷题笔记。文章整体分为两部分:
1.笔者自己思考的算法及代码。
2.LeetCode官方给出的最优算法及代码。通过对比这两部分算法和代码的异同,笔者的算法思想和编程水平有了显著地提升。如果这篇文章能帮到你那真是再好不过了!
一、笔者思考的算法
A.算法
本题的算法主要为模拟填入数字的过程,也可以说没什么算法,就是单纯地模拟过程。
难点:
1. 每一个螺旋循环都要遵循相同的步骤,而且要保证左闭右开原则。
2. 填入数字的过程中,从哪里开始,到哪里结束,i.e.遍历数组的始终条件startx+n-offset是一个关键点。
class Solution(object):
def generateMatrix(self, n):
"""
:type n: int
:rtype: List[List[int]]
"""
startx = starty = 0 //矩阵起点坐标
loop = mid = n // 2 //由n决定的循环次数以及中心块坐标(当n为奇数时)
offset = 1 //用来确定给每一条边赋值时的长度
count = 1
res = [ [0]*n for _ in range(n) ] //初始化矩阵
curr_j = curr_i = 0 //最近一次被插入元素的坐标
while loop: //当循环次数不为0时,进入while
for j in range(starty, starty + n - offset): //range的右边界遵循的规律
res[startx][j] = count //横轴不动,依次遍历纵轴并赋值
count += 1
curr_j = j //由于for循环的j在循环结束后被释放,需要curr_j保存
curr_j += 1 //+1 才能得出下一条边的纵轴坐标
for i in range(startx, startx + n - offset):
res[i][curr_j] = count
count += 1
curr_i = i
curr_i += 1
for j in range(curr_j, starty, -1):
res[curr_i][j] = count
count += 1
curr_j = j
curr_j -= 1
for i in range(curr_i, startx, -1):
res[i][curr_j] = count
count += 1
curr_i = i
startx += 1
starty += 1
loop -= 1
offset += 2 //减去外圈的两个元素
if n % 2: //当n为奇数时,需要单独给中心块赋值
res[mid][mid] = count
return res
B.复杂度分析
时间复杂度:O(n^2) 观察每个数组元素被操作的次数,n*n矩阵每个元素都被操作过。
空间复杂度: O(1) 没用到额外空间。
二.官方算法
官方算法与我的算法几乎一致
三.笔者小结
1.此题关键点在于,按层模拟。
2.注意给每条边赋值时,横向或纵向数组个数的确定。