Set Matrix Zeroes

题目源自于Leetcode和Cracking Coding Interview。

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

思路:如果直接遍历整个矩阵,遇到0就把当前行当前列设为全0,那么最终会错误地将整个矩阵全变为0。所以要先过一遍,记住哪一行应该设为全0,那一列应该设为全0,然后第二次的时候再设0。

    关键点在辅助空间消耗上。最笨的办法是完全复制一个新的矩阵,在新的矩阵上设0,这样就不会出现刚才说的错误,可能遍历一遍搞定,空间开销是O(m*n)。好些的办法是申请一个行数组和一个列数组,分别记录每行、每列是否应该设为0, 空间开销是O(m + n)。题目提示出,能否让空间开销为O(1)。

    我想出了两个办法。

第一个办法是,遍历时遇到0,就把当前行当前列的非0的数全变为一个特殊的数(比如INT_MAX)。第二遍遍历时,把所有的特殊的数修改为0。不过,在提交答案的时候,测试数据矩阵中就含有我设置的特殊的数,没有别的特殊的数了,所以这个方法没走通。

第二个方法是,选取矩阵的第一行、第一列,作为刚才O(m + n)那个方法中的行数组和列数组,用来做记录。所以我得把他们单独拿出来,先处理这一行和这一列。


代码:

class Solution {
public:
    void setZeroes(vector<vector<int> > &matrix) {
        int m = matrix.size();
        if(m<=0)
            return;
        int n = matrix[0].size();
        if(n<=0)
            return;
        
        int i,j;
        int r0, c0;
        r0 = c0 = 0;
        for(i=0;i<m;i++) //先记住第一列最终是否要设置为全0
            if(matrix[i][0] == 0)
            {
                c0 = 1;
                break;
            }
        for(j=0;j<n;j++) //先记住第一行最终是否要设置为全0
            if(matrix[0][j] == 0)
            {
                r0 = 1;
                break;
            }
        
        for(i=0;i<m;i++) //第一遍全体遍历,做记录
            for(j=0;j<n;j++)
            {
                if(matrix[i][j] == 0)
                {
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                }
            }
        
        for(i=1;i<m;i++) //根据第一列的记录情况,设0
            if(matrix[i][0] == 0)
            {
                for(j=1;j<n;j++)
                    matrix[i][j] = 0;
            }
            
        for(j=1;j<n;j++) //根据第一行的记录情况,设0
            if(matrix[0][j] == 0)
            {
                for(i=1;i<m;i++)
                    matrix[i][j] = 0;
            }
            
        if(c0 == 1) //第一列设置为全0
        {
            for(i=0;i<m;i++)
                matrix[i][0] = 0; 
        }
        if(r0 == 1) //第一行设置为全0
        {
            for(j=0;j<n;j++)
                matrix[0][j] = 0;
        }
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值