面试题 01.08. 零矩阵

   如果直接开始for循环,遇到一个0就清空对应的行和列,那么最终会导致矩阵多出很多0(原本不是0的位置,遍历到的时候也被计为0

 

 

第一种方法

可以使用辅助矩阵:遍历矩阵的过程中,遇到一个0,就把它对应的行和列记入辅助矩阵(boolean类型)中,遍历结束后,根据辅助矩阵的值来对原矩阵进行改造。这种思路比较简单,代码也很好实现,但是它的空间复杂度为 O(MN)

第二种方法

那么我们就需要想一种对自身进行操作的方法,不需要辅助矩阵。我们可以使用第一行和第一列来记录是否存在0点。但是问题就是:如果第一行和第一列也存在0点,这样记录会被覆盖。因此我们需要用两个boolean变量来记录第一行和第一列是否存在零点,最后记录完成后再进行改造,改造的具体方法是:行和列分别从1开始遍历(因为第一行和第一列单独处理),如果对应的第一列或第一行为0,那么就清空对应对应行/列,注意行和列的清空是相反的

class Solution {
    public void setZeroes(int[][] matrix) {
        boolean ifRow=false,ifCol=false; //记录第一行和第一列是否有零
        int m = matrix.length, n = matrix[0].length;
        for(int i=0;i<m;i++){ //遍历第一列
            if(matrix[i][0]==0){ 
                ifCol = true;
            }
        }
        for(int i=0;i<n;i++){
            if(matrix[0][i]==0){
                ifRow = true;
            }
        }
        //记录完毕,接下来遍历矩阵
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(matrix[i][j]==0){
                    //用第一行和第一列记录
                    matrix[0][j]=0;
                    matrix[i][0]=0;
                }
            }
        }
        //从1开始(因为第一行和第一列要单独处理)
        for(int i=1;i<m;i++){ 
            if(matrix[i][0]==0){
                for(int j=1;j<n;j++){
                    matrix[i][j]=0;
                }
            }
        }
        for(int i=1;i<n;i++){
            if(matrix[0][i]==0){
                for(int j=1;j<m;j++){
                    matrix[j][i]=0;
                }
            }
        }
        if(ifRow){ //第一行原本就有0
            for(int i=0;i<n;i++)
                matrix[0][i]=0;
        }
        if(ifCol){ //第一列原本就有0
            for(int i=0;i<m;i++)
                matrix[i][0]=0;
        }
    }
}

 

posted @ 2021-12-23 10:08  Acc22222222  阅读(66)  评论(0)    收藏  举报