LeetCode 73. Set Matrix Zeroes

本文介绍了一种在常数空间复杂度下对矩阵中含0元素的行和列进行置零的算法。通过巧妙利用矩阵的第一行和第一列来标记哪些行和列需要被置零,避免了使用额外的空间。

Description

Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.

Follow up:
Did you use extra space?
A straight forward 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?

Analysis

题意是对任何含0元素的行或列整体置0。
本身是一道简单的题,Follow up中提到了很容易想到的两种思路:

  • O(mn):存一份矩阵的副本,然后遍历该副本(因为题目中函数参数传递的是引用,所以直接该原矩阵比较方便),碰到0元素就将原矩阵中的对应行列全部置0。
  • O(m+n):开一个bool数组,元素共m+n个,存储第m行(或第n列)是否含0,然后根据该数组对原矩阵置0。

但题目要求我们调整到常数的空间复杂度。实际上,O(m+n)的方法提示我们,我们只需要这m+n个bit就可以正确置0该矩阵,那么可以考虑直接将这些信息存入矩阵,为了方便我选取了第0行和第0列。那么思路如下:

  1. 先遍历第0行和第0列,确定其中是否含0,用布尔型变量l0c0记录;
  2. 遍历矩阵剩余元素,若发现0,则在(对应行,0)(0,对应列)处用0记录;
  3. 遍历第0行和第0列,若为0,则将对应行/列全部置0;
  4. 查看l0c0,若含0,则对应对第0行或第0列置0。

Code

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int c = matrix[0].size(), l = matrix.size(), i, j;
        bool l0 = false, c0 = false;
        for (i = 0; i < l; i++)
            if (matrix[i][0] == 0){
                l0 = true;
                break;
            }
        for (j = 0; j < c; j++)
            if (matrix[0][j] == 0){
                c0 = true;
                break;
            }
        for (i = 1; i < l; i++)
            for (j = 1; j < c; j++){
                if (matrix[i][j] == 0){
                    matrix[0][j] = 0;
                    matrix[i][0] = 0;
                }
            }
        for (i = 1; i < l; i++)
            if (matrix[i][0] == 0)
                for (j = 1; j < c; j++)
                    matrix[i][j] = 0;
        for (j = 1; j < c; j++)
            if (matrix[0][j] == 0)
                for (i = 1; i < l; i++)
                    matrix[i][j] = 0;
        if (l0){
            for (i = 0; i < l; i++)
                matrix[i][0] = 0;
            }
        if (c0){
            for (j = 0; j < c; j++)
                matrix[0][j] = 0;
            }        
        }
};

Appendix

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值