返回

算法题每日一练:矩阵置零

前端

作为一名勤奋的程序员,每日一练是精进技艺的必经之路。今天,我们深入算法丛林,探索一道经典难题——矩阵置零。

这道题目看似简单,却暗藏玄机,考验着我们的算法思维和代码实现能力。题目要求我们针对一个 m x n 的矩阵,若其某个元素为 0,则将其所在行和列的所有元素都置为 0。关键在于,我们必须使用原地算法,即在不创建新矩阵的情况下修改原矩阵。

为了解决这一难题,我们采用分治策略,将矩阵分为两部分:已处理元素和待处理元素。我们首先遍历矩阵的第一行和第一列,寻找 0 元素。如果找到,则将该行和列的所有元素标记为要置零。

接下来,我们按行遍历矩阵的其余部分,对于每一行,如果其第一列元素被标记为要置零,则将该行所有元素置为 0。否则,我们遍历该行的剩余部分,若发现 0 元素,则将该行和该元素所在的列的所有元素标记为要置零。

通过这种方式,我们巧妙地利用了矩阵的第一行和第一列作为标记区域,避免了重复标记,确保了算法的时间复杂度为 O(mn),其中 m 和 n 分别表示矩阵的行数和列数。

算法伪代码如下:

for i in range(m):
    for j in range(n):
        if matrix[i][j] == 0:
            # 将该行和该元素所在的列的所有元素标记为要置零
            for k in range(m):
                matrix[k][j] = -1
            for k in range(n):
                matrix[i][k] = -1

for i in range(m):
    for j in range(n):
        if matrix[i][j] == -1:
            # 将该行和该元素所在的列的所有元素置为 0
            for k in range(m):
                matrix[k][j] = 0
            for k in range(n):
                matrix[i][k] = 0

举个例子,考虑一个 3 x 4 的矩阵:

[[1, 2, 0, 4],
 [5, 0, 7, 8],
 [9, 10, 11, 12]]

算法处理后,矩阵变为:

[[0, 0, 0, 0],
 [0, 0, 0, 0],
 [9, 0, 11, 12]]

算法的精妙之处在于,它仅用一个标记来标记需要置零的行和列,从而节省了大量的空间开销。这种思想在解决其他类似问题时也具有借鉴意义。

通过这道算法题,我们不仅提高了算法思维能力,还加深了对原地算法的理解。只要我们不断练习,精益求精,就能在算法丛林中披荆斩棘,不断取得进步。