LeetCode 中级 - 矩阵置零

矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。

示例 1:

输入: 
[
  [1,1,1],
  [1,0,1],
  [1,1,1]
]
输出: 
[
  [1,0,1],
  [0,0,0],
  [1,0,1]
]

示例 2:

输入: 
[
  [0,1,2,0],
  [3,4,5,2],
  [1,3,1,5]
]
输出: 
[
  [0,0,0,0],
  [0,4,5,0],
  [0,3,1,0]
]

进阶:

  • 一个直接的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
  • 一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
  • 你能想出一个常数空间的解决方案吗?

分析

首先这题最重要的一点,是如何处理置0后,不会影响后续遍历结果。也就是要避免在某次操作中我将a[i][j]置0,而之后我遍历到a[i][j]元素时,其原本的值丢失,导致最后数组所有元素都是0。

如果允许O(mn)空间:直接新开一个m*n的数组,扫描原数组,置0操作在新数组中执行,这样就不必担心置0后续遍历的结果。

如果允许O(m+n)空间。那么可以分别开两个m,n长度的数组,分别记录这一行/这一列中有没有0出现,有则置0,最后根据这两个数组哪些元素为0即可判断哪些行以及哪些列需要置0。(用0来做记录原因是我们不知道数组中存在哪些值,唯有使用0这个特殊值)

而如果只允许常数空间,我们就需要对上面O(m+n)的解法进一步优化,我们直接使用原数组的第一行和第一列元素记录当前行或者当前列中除本身以外是否存在0,如果存在0,则将首元素置0,如用a[2][0]记录第3行中除了a[2][0]以外的元素中是否存在0,如果后者中出现0了,那么我们将a[2][0]置0。

但是这样有一个问题:我如何处理第一行或者第一列中本身就有0存在?因此我们又需要额外两个变量firstRowIsZero,firstColIsZero判断第一行以及第一列本身是否存在0。

这样我们先对除了第一行第一列以外的元素进行置0,在根据上面两个变量来判断是否对第一行第一列置0

代码

class Solution {
        //用第一行的元素表示每一列是否存在0,第一列的元素表示每一行是否存在0
        //同时要处理第一行第一列本身存在0的情况
        public void setZeroes(int[][] matrix) {
            if(matrix.length == 0){
                return;
            }
            boolean firstRowIsZero = false,firstColIsZero = false;
            for(int i =0;i<matrix.length;i++){
                for(int j=0;j<matrix[0].length;j++){
                    if(i!=0 && j!=0 && matrix[i][j]==0){
                        matrix[i][0]=0;
                        matrix[0][j]=0;
                    }else if(matrix[i][j]==0){
                        firstRowIsZero = i==0? true:firstRowIsZero;
                        firstColIsZero = j==0? true:firstColIsZero;
                    }
                }
            }
            for(int i=1;i<matrix.length;i++){
                for(int j=1;j<matrix[0].length;j++){
                    if(matrix[0][j]==0 || matrix[i][0] == 0){
                        matrix[i][j]=0;
                    }
                }
            }
            //第一列含0
            if(firstColIsZero){
                for(int i=0;i<matrix.length;i++){
                    matrix[i][0] = 0;
                }
            }
            //第一行含0
            if(firstRowIsZero){
                for(int j=0;j<matrix[0].length;j++){
                    matrix[0][j] = 0;
                }
            }
        }
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值