题目描述
给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。
示例 1:
| 1 | 输入: | 
示例 2:
| 1 | 输入: | 
进阶:
- 一个直接的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
- 一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
- 你能想出一个常数空间的解决方案吗?
题解
题目乍看比较简单,但是比较坑的地方在于原地修改,修改时需要记录原本是0的元素。
额外空间
空间复杂度 $O(M \times N)$
思路
- 遍历所有节点,如果 matrix[i][j]为0,则将所在行i与列j的所有元素置为0。
- 记录一个二维数组 visited[][],表示这个节点是否访问过。
- 置 0过程中,将访问数组visited[i][j]记录为true。如果原本值已经为0,则记录为false,以便下次可以扫描到。
复杂度
- 时间复杂度:$O((M \times N) \times (M+N))$
- 空间复杂度:$O(M \times N)$
代码
| 1 | // C++ | 
空间复杂度 $O(M+N)$
思路
- 第一次遍历所有元素,使用 zeroRows[M]和zeroCols[N]来记录哪些行和列有0元素存在。
- 第二次遍历根据记录,如果 zeroRows[i] == true || zeroCols[j] == true,则将matrix[i][j]置为0。
复杂度
- 时间复杂度:$O(M \times N)$
- 空间复杂度:$O(M + N)$
代码
| 1 | // C++ | 
暴力法 空间复杂度 $O(1)$
思路
- 第一次遍历,如果 matrix[i][j]为0,则修改所在行i与列j的所有元素,将所有非0元素置为一个特殊值MODIFED = -1000000,说明该位置的元素被修改过。
- 第二次遍历,如果 matrix[i][j] == MODIFIED,则将其置为0。
复杂度
- 时间复杂度:$O((M \times N) \times (M + N))$
- 空间复杂度:$O(1)$
代码
| 1 | // C++ | 
改进方案 空间复杂度 $O(1)$
算法
- 遍历整个矩阵,将矩阵的第一行和第一列的所有元素做为标志位,代表这行或这列需要置为 0。
| 1 | if matrix[i][j] == 0 { | 
- 由于第一行与第一列被用作标志位,所以需要额外的变量标记第一行与第一列, - isCol记录第一列是否需要置- 0,- matrix[0][0]则用来标记第一行是否需要置- 0。
- 从第二行与第二列即 - matrix[1][1]开始遍历- 1 
 2
 3- if matrix[i][0] == 0 || matrix[i][1] == 0 { 
 matrix[i][j] = 0;
 }
- 如果 - matrix[0][0] == 0,则第一行置为- 0。
- 如果 isCol == true,则第一列置为0。
复杂度
- 时间复杂度:$O(M \times N)$
- 空间复杂度:$O(1)$
代码
| 1 | // C++ | 
参考链接
- 73. Set Matrix Zeroes, LeetCode solution.