在数据结构中我很少看到单独讲矩阵的,突然看到了拿出来讲的很新鲜,但矩阵确实是一个很重要的工具:对于矩阵的操作主要包括旋转,缩放,遍历等。而且已经经历过很多矩阵的应用场景。
题目描述很简单,一个矩阵中任何位置发现了零,则将该元素所在的行和列,都变成零,有一种病毒传播的感觉。暂且称为零的传播哈哈。
一种简单的做法是重新构建一个矩阵,对原矩阵进行遍历,如果发现了零,则将新的矩阵的相对的行列都设置为零,最终再将所有元素拿回来。可以想象如果矩阵很大,就会有很高的时间和空间复杂度。
实现步骤:
代码实现:
def set_matrix_zeros(mat):
rows, cols = len(mat), len(mat[0])
frow, fcol = False, False
for i in range(rows):
if mat[i][0] == 0:
fcol = True
break
for j in range(cols):
if mat[0][j] == 0:
frow = True
break
for r in range(1, rows):
for c in range(1, cols):
if mat[r][c] == 0:
mat[0][c], mat[r][0] = 0, 0
for i in range(1, rows):
if mat[i][0] == 0:
for j in range(1, cols):
mat[i][j] = 0
for j in range(1, cols):
if mat[0][j] == 0:
for i in range(1, rows):
mat[i][j] = 0
if frow:
for j in range(cols):
mat[0][j] = 0
if fcol:
for i in range(rows):
mat[i][0] = 0
return mat
学习笔记:
中规中矩地按照步骤自己写了解答,和答案没有区别就不贴答案了,时间复杂度为O(mxn),空间复杂度为O(1),因为没有使用额外的空间。
将一个正方形矩阵向右九十度旋转的问题。
以下是解决这个问题的步骤总结:
通过这些步骤,我们可以完成矩阵的顺时针旋转90度。
说实话这个步骤我很迷惑,比如对角线的右手边的两个元素要走一个Z字形,我理解了题解的方法是从可视化表示才理解的。
我更喜欢自己这个思路:
仅此而已。而且这两种方法的时间复杂度都是O(n^2),空间复杂度都是O(1)。
首先是我觉得自己的这种比较好理解的方法:转置和左右逆。
def rotate_image(matrix):
n = len(matrix)
for i in range(n):
for j in range(i, n):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
for i in range(n):
matrix[i] = matrix[i][::-1]
return matrix
以下是官方的三次旋转法的题解:
def rotate_image(matrix):
n = len(matrix)
for row in range(n // 2):
for col in range(row, n - row - 1):
matrix[row][col], matrix[col][n - 1 - row] = matrix[col][n - 1 - row], matrix[row][col]
matrix[row][col], matrix[n - 1 - row][n - 1 - col] = matrix[n - 1 - row][n - 1 - col], matrix[row][col]
matrix[row][col], matrix[n - 1 - col][row] = matrix[n - 1 - col][row], matrix[row][col]
return matrix
学习笔记:矩阵的算法还是挺快乐的。
对一个矩阵进行螺旋遍历,从左上角开始顺时针。将遍历的数字存储在数组中。简单来说就是一个矩阵螺旋遍历的问题。
以下是代码的步骤方法总结:
代码以及对照答案修改过后:
def spiral_order(matrix):
rows, cols = len(matrix), len(matrix[0])
r, c = 0, -1
direction = 1
result = []
while rows > 0 and cols > 0:
for _ in range(cols):
c += direction
result.append(matrix[r][c])
rows -= 1
for _ in range(rows):
r += direction
result.append(matrix[r][c])
cols -= 1
direction *= -1
return result
学习笔记:时间复杂度是遍历的长度也就是O(m x n),也就是整个矩阵的大小。空间复杂度为O(1),因为没有使用额外的空间。这是一道很不错的题。查了一下还有一种活用内置函数zip()
来模拟顺时针遍历螺旋矩阵的过程。好聪明。具体步骤如下:
以下是这种方法的Python代码实现:
def spiral_order(matrix):
result = []
while matrix:
result += matrix.pop(0)
matrix = list(zip(*matrix))[::-1]
return result
这种方法简洁明了,利用了Python内置函数的强大功能,而不需要手动控制遍历方向。