Leetcode 73. Set Matrix Zeroes

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?

思路:
1. 这道题麻烦就麻烦在:矩阵自身含有的0和通过对i行j列置0得到的0,如何区分?这题不无聊,有点趣味!
2. 简单粗暴不优化的方法很容易从脑袋里蹦出来。O(mn)的空间:新建一个m*n的矩阵,初始化-1,然后遍历一遍给的矩阵,发现matrix[i][j]==0,则把对应的新矩阵的i行j列置为0,然后遍历新矩阵,把不为0的位置用旧矩阵同样的位置替代。
2. 空间上肯定可以优化,比如o(m+n),我们对每行每列都要置为相同的数,说明没必要用O(mn)的矩阵保存这么多信息。每一行、每一列只需要一个指示就够了。因此,新建vector< bool> row(m,0)和vector< bool> col(n,0),遍历给的矩阵,遇到0就用对应坐标[i,j]去标识row[i]=1,col[j]=1;最后,再遍历一遍矩阵,对坐标[i,j]查询row和col,if(row[i]=1或col[j]=1)则matrix[i][j]=0;
3. 如果说还可以做成o(1)的空间的话?就只有一些trick的方法了,比如:用给定的矩阵来复用,保存标志位。例如:if(matrix[i][j]==0),则把i行最左边和j列最上边的值置位0;等遍历完一遍后,根据标志位,把整行整列都置0,这又要方位两次。
4. 仔细观察这些思路:都是试图先把所有的0的位置掌握清楚后,再统一归0。从而避免了刚开始面临的问题:如何区分矩阵自身含有的0和通过对i行j列置0得到的0。因此解决问题的核心是:把问题分成两部分先后完成,而不是交叉完成!
5.方法1是空间复用的做法。首先:标记第一行,第一列是否有0;然后遍历除第一行第一列的其他部分,置位第一行第一列;再遍历一次,根据第一行第一列是否为0来置位;最后根据之前关于第一行第一列是否包含0来置位第一行第一列!总共分四步!!!

//方法1:空间复用
class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        //
        int m=matrix.size();
        if(m==0) return;//超级无敌bug,弄晕了半个小时!!!错误写成if(m=0)!!
        int n=matrix[0].size();
        //把第一行,第一列用来保存标识位
        //第一行,第一列是否包含0用标志位单独记录!
        int row=0,col=0;
        for(int i=0;i<m;i++){
            if(matrix[i][0]==0){
                row=1;
                break;
            }
        }
        for(int j=0;j<n;j++){
            if(matrix[0][j]==0){
                col=1;
                break;
            }
        }
        for(int i=1;i<m;i++){
            for(int j=1;j<n;j++){
                if(matrix[i][j]==0){
                    matrix[i][0]=0;
                    matrix[0][j]=0; 
                }
            }
        }
        for(int i=1;i<m;i++){
            for(int j=1;j<n;j++){
                if(matrix[i][0]==0||matrix[0][j]==0)
                    {matrix[i][j]=0;
                    }
            }
        }
        if(row==1){
            for(int i=0;i<m;i++)
                matrix[i][0]=0;
        }
        if(col==1){
            for(int j=0;j<n;j++)
                matrix[0][j]=0;
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值