LeetCode-73-Set Matrix Zeroes-M(数组元素置为0)

本文介绍了一种高效的矩阵零填充算法,旨在将矩阵中任意位置的零元素所在行和列全部置零,提供了两种解决方案,一种使用O(m+n)空间复杂度,另一种则实现了常数空间复杂度O(1),通过巧妙利用矩阵内数据避免了额外空间的开销。

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

Follow up:

  • 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?

比较容易想到的办法:用两个boolean数组来维护之前矩阵为0的位置,然后更换矩阵元素。空间复杂度为O(m+n)

class Solution {
    public void setZeroes(int[][] matrix) {
        int m=matrix.length;
        int n=matrix[0].length;
        boolean[] row=new boolean[m];
        boolean[] col=new boolean[n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(matrix[i][j]==0){
                    row[i]=true;
                    col[j]=true;
                }
            }
        }
        for(int i=0;i<m;i++){
            if(row[i]){
                for(int j=0;j<n;j++){
                    matrix[i][j]=0;
                }
            }
        }
        for(int j=0;j<n;j++){
            if(col[j]){
                for(int i=0;i<m;i++){
                    matrix[i][j]=0;
                }
            }
        }
    }
}

一个空间复杂度为O(1)的方法:

1.找到一个全不为0的noZeroRow行,用这个行来记录每个列是否有零。

2.把所有有0的行的所有元素置为0。(除了noZeroRow行)

3.再把noZeroRow行所有0对应的列所有元素置为0。

(即用这个noZeroRow行完成了之前两个boolean数组的功能,不需要额外的空间)

class Solution {
    public void setZeroes(int[][] matrix) {

        int noZeroRow=-1;//标记全不为0的行
        int m=matrix.length;
        int n=matrix[0].length;

        for(int i=0;i<m;i++){
            int j=0;
            for(;j<n;j++){
                if(matrix[i][j]==0)
                    break;
            }
            if(j==n)//如果遍历到了最后仍然没有发现0,说明这一行全不为0
                noZeroRow=i;
        }

        if(noZeroRow==-1){//说明每一行都有0,整个矩阵赋为0
            for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    matrix[i][j]=0;
                }
            }
        }else{//用这不为0的行来记录所有存在0的列
            for(int i=0;i<m;i++){
               for(int j=0;j<n;j++){
                   if(matrix[i][j]==0)
                       matrix[noZeroRow][j]=0;
                }
            }
            for(int i=0;i<m;i++){
                //跳过noZeroRow行
                if(i==noZeroRow)
                    continue;
                for(int j=0;j<n;j++){
                    if(matrix[i][j]==0){
                        for(int j2=0;j2<n;j2++){
                            //把存在0的行的所有数置为0
                            matrix[i][j2]=0;
                        }
                    }
                }
            }
            for(int j=0;j<n;j++){
                //noZeroRow记录下来原本存在0的列,现在把这些列全置为0
                if(matrix[noZeroRow][j]==0){
                    for(int i=0;i<m;i++){
                        matrix[i][j]=0;
                    }
                }
            }
        }
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值