Python算法题集_螺旋矩阵
- 题目54:螺旋矩阵
- 1. 示例说明
- 2. 题目解析
- - 题意分解
- - 优化思路
- - 测量工具
- 3. 代码展开
- 1) 标准求解【检测4个方向】
- 2) 改进版一【检测2个方向】
- 3) 改进版二【可读性改进】
- 4. 最优算法
题目54:螺旋矩阵
本文为Python算法题集之一的代码示例
1. 示例说明
-
给你一个
m
行n
列的矩阵matrix
,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5]
示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] 输出:[1,2,3,4,8,12,11,10,9,5,6,7]
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100
2. 题目解析
- 题意分解
- 本题为矩阵寻路算法
- 本题的主要计算是元素遍历,算法时间复杂度为O(m*n)
- 基本的解法是按当前逐步移动到边界,然后按螺旋转向
- 优化思路
-
通常优化:减少循环层次
-
通常优化:增加分支,减少计算集
-
通常优化:采用内置算法来提升计算速度
-
分析题目特点,分析最优解
- 此题好像没有什么大的优化空间,主要是减少比较计算的次数
- 测量工具
- 本地化测试说明:LeetCode网站测试运行时数据波动很大,因此需要本地化测试解决这个问题
CheckFuncPerf
(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块- 本题超时测试用例自行生成,代码详见【4.最优算法】
3. 代码展开
1) 标准求解【检测4个方向】
本题没有太多优化空间,标准代码指标就很高 指标优越,超越95%
import CheckFuncPerf as cfp
def spiralOrder_base(matrix):
result = []
if not matrix:
return result
iheight, iwidth = len(matrix), len(matrix[0])
itop, ibottom = 0, iheight - 1
ileft, iright = 0, iwidth - 1
while itop <= ibottom and ileft <= iright:
if itop <= ibottom:
for iIdx in range(ileft, iright + 1):
result.append(matrix[itop][iIdx])
itop += 1
if ileft <= iright:
for iIdx in range(itop, ibottom + 1):
result.append(matrix[iIdx][iright])
iright -= 1
if itop <= ibottom:
for iIdx in range(iright, ileft - 1, -1):
result.append(matrix[ibottom][iIdx])
ibottom -= 1
if ileft <= iright:
for iIdx in range(ibottom, itop - 1, -1):
result.append(matrix[iIdx][ileft])
ileft += 1
return result
import random, copy
matrix = []
for iIdx in range(1000):
matrix.append([random.randint(0, 10) for x in range(1000)])
matrixCopy = copy.deepcopy(matrix)
result = cfp.getTimeMemoryStr(spiralOrder_base, matrixCopy)
print(result['msg'])
# 运行结果
函数 spiralOrder_base 的运行时间为 93.02 ms;内存使用量为 8072.00 KB
2) 改进版一【检测2个方向】
经过调试,确认外部边界后,有两个方向可以不进行比较 君临天下,九九归一(99%)
import CheckFuncPerf as cfp
def spiralOrder_ext1(matrix):
result = []
if not matrix:
return result
iheight, iwidth = len(matrix), len(matrix[0])
itop, ibuttom, ileft, iright = 0, iheight - 1, 0, iwidth - 1
while itop <= ibuttom and ileft <= iright:
for iIdx in range(ileft, iright + 1):
result.append(matrix[itop][iIdx])
itop += 1
for iIdx in range(itop, ibuttom + 1):
result.append(matrix[iIdx][iright])
iright -= 1
if itop <= ibuttom:
for iIdx in range(iright, ileft - 1, -1):
result.append(matrix[ibuttom][iIdx])
ibuttom -= 1
if ileft <= iright:
for iIdx in range(ibuttom, itop - 1, -1):
result.append(matrix[iIdx][ileft])
ileft += 1
return result
import random, copy
matrix = []
for iIdx in range(1000):
matrix.append([random.randint(0, 10) for x in range(1000)])
matrixCopy = copy.deepcopy(matrix)
result = cfp.getTimeMemoryStr(spiralOrder_ext1, matrixCopy)
print(result['msg'])
# 运行结果
函数 spiralOrder_ext1 的运行时间为 91.03 ms;内存使用量为 8484.00 KB
3) 改进版二【可读性改进】
进行可读改进,行列变量更名,块逻辑稍微调整 表现优异,超过98%
import CheckFuncPerf as cfp
def spiralOrder_ext2(matrix):
result = []
if not matrix:
return result
iheight, iwidth = len(matrix), len(matrix[0])
ileft, iright, itop, ibottom = 0, iwidth - 1, 0, iheight - 1
while ileft <= iright and itop <= ibottom:
for aColno in range(ileft, iright + 1):
result.append(matrix[itop][aColno])
for aRowno in range(itop + 1, ibottom + 1):
result.append(matrix[aRowno][iright])
if ileft < iright and itop < ibottom:
for bColno in range(iright - 1, ileft, -1):
result.append(matrix[ibottom][bColno])
for bRowno in range(ibottom, itop, -1):
result.append(matrix[bRowno][ileft])
ileft += 1
iright -= 1
itop += 1
ibottom -= 1
return result
import random, copy
matrix = []
for iIdx in range(1000):
matrix.append([random.randint(0, 10) for x in range(1000)])
matrixCopy = copy.deepcopy(matrix)
result = cfp.getTimeMemoryStr(spiralOrder_ext2, matrixCopy)
print(result['msg'])
# 运行结果
函数 spiralOrder_ext2 的运行时间为 92.03 ms;内存使用量为 7340.00 KB
4. 最优算法
根据本地日志分析,本题算法指标极为接近,最优算法为第2种spiralOrder_ext1
import random, copy
matrix = []
for iIdx in range(1000):
matrix.append([random.randint(0, 10) for x in range(1000)])
matrixCopy = copy.deepcopy(matrix)
# 算法本地速度实测比较
函数 spiralOrder_base 的运行时间为 93.02 ms;内存使用量为 8072.00 KB
函数 spiralOrder_ext1 的运行时间为 91.03 ms;内存使用量为 8484.00 KB
函数 spiralOrder_ext2 的运行时间为 92.03 ms;内存使用量为 7340.00 KB
一日练,一日功,一日不练十日空
may the odds be ever in your favor ~