Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[LeetCode] 73. Set Matrix Zeroes #73

Copy link
Copy link
Open
@grandyang

Description

@grandyang
Issue body actions


请点击下方图片观看讲解视频
Click below image to watch YouTube Video
Video

Given an m x n integer matrix matrix, if an element is 0, set its entire row and column to 0's.

You must do it in place.

Example 1:

Input: matrix = [[1,1,1],[1,0,1],[1,1,1]]
Output: [[1,0,1],[0,0,0],[1,0,1]]

Example 2:

Input: matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
Output: [[0,0,0,0],[0,4,5,0],[0,3,1,0]] 

Constraints:

  • m == matrix.length
  • n == matrix[0].length
  • 1 <= m, n <= 200
  • -2^31 <= matrix[i][j] <= 2^31 - 1

Follow up:

  • A straightforward solution using O(mn) space is probably a bad idea.
  • A simple improvement uses O(m + n) space, but still not the best solution.
  • Could you devise a constant space solution?

据说这题是 CareerCup 上的原题,也不算难,虽然博主也是看了网上的解法照着写的,但是下次遇到绝对想的起来。这道题中说的空间复杂度为 O(mn) 的解法自不用多说,直接新建一个和 matrix 等大小的矩阵,然后一行一行的扫,只要有0,就将新建的矩阵的对应行全赋0,行扫完再扫列,然后把更新完的矩阵赋给 matrix 即可,这个算法的空间复杂度太高。将其优化到 O(m+n) 的方法是,用一个长度为m的一维数组记录各行中是否有0,用一个长度为n的一维数组记录各列中是否有0,最后直接更新 matrix 数组即可。这道题的要求是用 O(1) 的空间,那么就不能新建数组,就用原数组的第一行第一列来记录各行各列是否有0.

- 先扫描第一行第一列,如果有0,则将各自的 flag 设置为 true
- 然后扫描除去第一行第一列的整个数组,如果有0,则将对应的第一行和第一列的数字赋0
- 再次遍历除去第一行第一列的整个数组,如果对应的第一行和第一列的数字有一个为0,则将当前值赋0
- 最后根据第一行第一列的 flag 来更新第一行第一列

解法一:

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int m = matrix.size(), n = matrix[0].size();
        bool rowZero = false, colZero = false;
        for (int i = 0; i < m; ++i) {
            if (matrix[i][0] == 0) colZero = true;
        }
        for (int i = 0; i < n; ++i) {
            if (matrix[0][i] == 0) rowZero = true;
        } 
        for (int i = 1; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                if (matrix[i][j] == 0) {
                    matrix[0][j] = 0;
                    matrix[i][0] = 0;
                }
            }
        }
        for (int i = 1; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                if (matrix[0][j] == 0 || matrix[i][0] == 0) {
                    matrix[i][j] = 0;
                }
            }
        }
        if (rowZero) {
            for (int i = 0; i < n; ++i) matrix[0][i] = 0;
        }
        if (colZero) {
            for (int i = 0; i < m; ++i) matrix[i][0] = 0;
        }
    }
};

我们可以稍微优化一下上面的解法,少用几个 for 循环,这里只用一个变量 colZero 来表示首列是否有0存在即可,首行不用单独去记录,因为其是否为0会在 matrix[0][0] 中记录。这里只需要两个嵌套 for 循环就可以了,第一个嵌套 for 循环的i是从0开始遍历的,若首列有0,则将 colZero 标记为 true。内层 for 循环的j是从1开始遍历的,若 matrix[i][j] 为0了,则将 matrix[0][j] 和 matrix[i][0] 都赋值为0。然后开始第二个嵌套 for 循环,外层的 for 循环的i是从 m-1 往前遍历到0,内层的 for 循环的j是从 n-1 往前遍历到1,若 matrix[0][j] 和 matrix[i][0] 中任意一个为0了,则将 matrix[i][j] 赋值为0,同时在外层 for 循环的遍历过程中,判断若 colZero 为 true,则将 matrix[i][0] 赋值为0,这就保证了首列被更新了,参见代码如下:

解法二:

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int m = matrix.size(), n = matrix[0].size();
        bool colZero = false;
        for (int i = 0; i < m; ++i) {
            if (matrix[i][0] == 0) colZero = true;
            for (int j = 1; j < n; ++j) {
                if (matrix[i][j] == 0) {
                    matrix[0][j] = 0;
                    matrix[i][0] = 0;
                }
            }
        }
        for (int i = m - 1; i >= 0; --i) {
            for (int j = n - 1; j >= 1; --j) {
                if (matrix[0][j] == 0 || matrix[i][0] == 0) {
                    matrix[i][j] = 0;
                }
            }
            if (colZero) matrix[i][0] = 0;
        }
    }
};

Github 同步地址:

#73

类似题目:

Game of Life

Number of Laser Beams in a Bank

Minimum Operations to Remove Adjacent Ones in Matrix

Remove All Ones With Row and Column Flips II

参考资料:

https://leetcode.com/problems/set-matrix-zeroes/

https://leetcode.com/problems/set-matrix-zeroes/solutions/26014/any-shorter-o-1-space-solution/

LeetCode All in One 题目讲解汇总(持续更新中...)

(欢迎加入博主的知识星球,博主将及时答疑解惑,并分享刷题经验与总结,快快加入吧~)

知识星球 喜欢请点赞,疼爱请打赏❤️~.~

微信打赏

|

Venmo 打赏


---|---

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.