• 面试金典08(Python)—— 零矩阵(中等)


    矩阵

    概述:编写一种算法,若 M × N 矩阵中某个元素为 0 ,则将其所在的行与列清零。

    1. 输入:
    2. [
    3. [1,1,1],
    4. [1,0,1],
    5. [1,1,1]
    6. ]
    7. 输出:
    8. [
    9. [1,0,1],
    10. [0,0,0],
    11. [1,0,1]
    12. ]
    13. 输入:
    14. [
    15. [0,1,2,0],
    16. [3,4,5,2],
    17. [1,3,1,5]
    18. ]
    19. 输出:
    20. [
    21. [0,0,0,0],
    22. [0,4,5,0],
    23. [0,3,1,0]
    24. ]

    方法一:标记+循环

    思路:首先二重循环,标记出原矩阵里面元素为 0 的位置。再对标记列表循环,依次把行和列全部替换成 0

    1. # 标记+循环
    2. class Solution:
    3. def setZeroes(self, matrix: List[List[int]]) -> None:
    4. m = len(matrix)
    5. n = len(matrix[0])
    6. ans = []
    7. for i in range(m):
    8. for j in range(n):
    9. if matrix[i][j] == 0:
    10. ans.append([i,j])
    11. for i in ans:
    12. row = i[0]
    13. col = i[1]
    14. matrix[row] = [0] * n
    15. for x in range(m):
    16. matrix[x][col] = 0

    方法二:标记+数组循环

    思路:思路基本上一致,不同在于把原数组转成 array 处理,最后再转回 list 即可。

    1. # 标记+数组循环
    2. import numpy as np
    3. class Solution:
    4. def setZeroes(self, matrix: List[List[int]]) -> None:
    5. m = len(matrix)
    6. n = len(matrix[0])
    7. ans = []
    8. for i in range(m):
    9. for j in range(n):
    10. if matrix[i][j] == 0:
    11. ans.append([i,j])
    12. matrix_arr = np.array(matrix)
    13. for i in ans:
    14. row = i[0]
    15. col = i[1]
    16. matrix_arr[row, :] = [0] * n
    17. matrix_arr[:, col] = [0] * m
    18. matrix[:] = matrix_arr.tolist()

    方法三:True 标记法

    思路:该算法与前两个算法不同在于,先建立一个 False 列表,元素为 0 位置标记为 True 。再把 True 位置对应的元素更新成 0 即可。

    1. # True 标记法
    2. class Solution:
    3. def setZeroes(self, matrix: List[List[int]]) -> None:
    4. m = len(matrix)
    5. row = [False] * m
    6. n = len(matrix[0])
    7. col = [False] * n
    8. for i in range(m):
    9. for j in range(n):
    10. if matrix[i][j] == 0:
    11. row[i] = col[j] = True
    12. for i in range(m):
    13. for j in range(n):
    14. if row[i] or col[j] is True:
    15. matrix[i][j] = 0

    方法四:原地标记

    思路:该算法与前面的算法都不同,不需要开辟新的内存空间。只需要锁定第一行和第一列,依次对剩余的行列循环判断即可。最后需要注意的是,对第一行和第一列处理即可。

    1. # 原地标记
    2. class Solution:
    3. def setZeroes(self, matrix: List[List[int]]) -> None:
    4. m = len(matrix)
    5. n = len(matrix[0])
    6. flag_row = any(matrix[i][0] == 0 for i in range(m))
    7. flag_col = any(matrix[0][j] == 0 for j in range(n))
    8. for i in range(1, m):
    9. for j in range(1, n):
    10. if matrix[i][j] == 0:
    11. matrix[i][0] = matrix[0][j] = 0
    12. for i in range(1, m):
    13. for j in range(1, n):
    14. if matrix[i][0] == 0 or matrix[0][j] == 0:
    15. matrix[i][j] = 0
    16. if flag_row:
    17. for i in range(m):
    18. matrix[i][0] = 0
    19. if flag_col:
    20. for j in range(n):
    21. matrix[0][j] = 0

    总结

    题目有点像小时候玩的炸弹超人啊

  • 相关阅读:
    golang容易导致内存泄漏的几种情况
    [Java]线上监控诊断工具Arathas,入门使用
    7.HTML中列表标签
    Linux打包发布常用命令
    如何完美解决前端数字计算精度丢失与数字格式化问题?
    基于java+springboot的人事招聘信息网站
    Maven中央仓库地址大全
    设A和B是两个单链表(带头结点),其中元素递增有序。设计一个算法从A和B中的公共元素产生新链表C,要求不破坏A,B。
    快手资讯|快手推出多档世界杯相关节目
    keil程序载入硬件成功,但未按代码执行
  • 原文地址:https://blog.csdn.net/m0_61661179/article/details/127638533