本文为Python算法题集之一的代码示例
给定一个 m x n
的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法**。**
示例 1:
输入:matrix = [[1,1,1],[1,0,1],[1,1,1]]
输出:[[1,0,1],[0,0,0],[1,0,1]]
示例 2:
输入:matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
输出:[[0,0,0,0],[0,4,5,0],[0,3,1,0]]
提示:
m == matrix.length
n == matrix[0].length
1 <= m, n <= 200
-231 <= matrix[i][j] <= 231 - 1
进阶:
O(m*n)
的额外空间,但这并不是一个好的解决方案。O(m+n)
的额外空间,但这仍然不是最好的解决方案。通常优化:减少循环层次
通常优化:增加分支,减少计算集数量
通常优化:采用内置算法来提升计算速度
分析题目特点,分析最优解
必须对行列进行全扫描以确定所有0,任何一个行/列只要出现一个0就不需要再扫,可以用调度用的数据结构优化
调度用的数据可以存在输入的矩阵中,实现原地算法【空间复杂度O(1)】
CheckFuncPerf
(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块丧心病狂的三层循环,可谓可算尽算,不漏过任何角落,依旧没有超时;看起来超时测试用例还是不给力
import CheckFuncPerf as cfp
def setZeroes_base(matrix):
import copy
matrixcopy = copy.deepcopy(matrix)
ilenrow, ilencol = len(matrix), len(matrix[0])
for iIdx in range(ilenrow):
for jIdx in range(ilencol):
if matrixcopy[iIdx][jIdx] == 0:
for kIdx in range(ilenrow):
matrix[kIdx][jIdx] = 0
for kIdx in range(ilencol):
matrix[iIdx][kIdx] = 0
import random
matrix = []
for iIdx in range(1000):
matrix.append([random.randint(0,1) for x in range(1000)])
result = cfp.getTimeMemoryStr(setZeroes_base, matrix)
print(result['msg'], '执行结果 = {}'.format(result['result']))
# 运行结果
函数 setZeroes_base 的运行时间为 62147.93 ms;内存使用量为 336.00 KB 执行结果 = None
一个横向数组、一个纵向数组,检测需要置零的行列,算法相当于O(n^2) 君临天下,九九归一【超越99%】
import CheckFuncPerf as cfp
def setZeroes_ext1(matrix):
ilenrow, ilencol = len(matrix), len(matrix[0])
icmdrow, icmdcol = [0] * ilenrow, [0] * ilencol
for iIdx in range(ilenrow):
for jIdx in range(ilencol):
if matrix[iIdx][jIdx] == 0:
icmdrow[iIdx] = 1
icmdcol[jIdx] = 1
for iIdx in range(ilenrow):
if icmdrow[iIdx] > 0:
for jIdx in range(ilencol):
matrix[iIdx][jIdx] = 0
for iIdx in range(ilencol):
if icmdcol[iIdx] > 0:
for jIdx in range(ilenrow):
matrix[jIdx][iIdx] = 0
import random
matrix = []
for iIdx in range(1000):
matrix.append([random.randint(0,1) for x in range(1000)])
result = cfp.getTimeMemoryStr(setZeroes_ext1, matrix)
print(result['msg'], '执行结果 = {}'.format(result['result']))
# 运行结果
函数 setZeroes_ext1 的运行时间为 152.05 ms;内存使用量为 8.00 KB 执行结果 = None
在传入的矩阵中保存横向数组、纵向数组,因此空间复杂度为O(1) 表现优异,超过90%
import CheckFuncPerf as cfp
def setZeroes_ext2(matrix):
ilenrow, ilencol = len(matrix), len(matrix[0])
icmdrow, icmdcol = -1, -1
bNotfind = True
for iIdx in range(ilenrow):
for jIdx in range(ilencol):
if matrix[iIdx][jIdx] == 0:
if bNotfind:
icmdrow = iIdx
icmdcol = jIdx
bNotfind = False
matrix[icmdrow][jIdx] = 0
matrix[iIdx][icmdcol] = 0
if bNotfind:
return
for iIdx in range(ilenrow):
if iIdx != icmdrow:
if matrix[iIdx][icmdcol] == 0:
for jIdx in range(ilencol):
if jIdx != icmdcol:
matrix[iIdx][jIdx] = 0
for iIdx in range(ilencol):
if iIdx != icmdcol:
if matrix[icmdrow][iIdx] == 0:
for jIdx in range(ilenrow):
if jIdx != icmdrow:
matrix[jIdx][iIdx] = 0
for iIdx in range(ilenrow):
matrix[iIdx][icmdcol] = 0
for iIdx in range(ilencol):
matrix[icmdrow][iIdx] = 0
import random
matrix = []
for iIdx in range(1000):
matrix.append([random.randint(0,1) for x in range(1000)])
result = cfp.getTimeMemoryStr(setZeroes_ext2, matrix)
print(result['msg'], '执行结果 = {}'.format(result['result']))
# 运行结果
函数 setZeroes_ext2 的运行时间为 508.10 ms;内存使用量为 0.00 KB 执行结果 = None
根据本地日志分析,最优算法为第2种setZeroes_ext1
import random
matrix = []
for iIdx in range(1000):
matrix.append([random.randint(0,1) for x in range(1000)])
# 算法本地速度实测比较
函数 setZeroes_base 的运行时间为 62147.93 ms;内存使用量为 336.00 KB 执行结果 = None
函数 setZeroes_ext1 的运行时间为 152.05 ms;内存使用量为 8.00 KB 执行结果 = None
函数 setZeroes_ext2 的运行时间为 508.10 ms;内存使用量为 0.00 KB 执行结果 = None
一日练,一日功,一日不练十日空
may the odds be ever in your favor ~