Likou 73. Matrix zeroing---three-method solution (use extra space, use two variables, use one variable)

73. Matrix Zeroing

Given an mxn matrix, if an element is 0, set all the elements in its row and column to 0. Please use the in-place algorithm.

Advanced:

An intuitive solution is to use O(mn) extra space, but this is not a good solution.
A simple improvement is to use O(m + n) extra space, but this is still not the best solution.
Can you think of a solution that uses only constant space?

示例 1:


输入:matrix = [[1,1,1],[1,0,1],[1,1,1]]
输出:[[1,0,1],[0,0,0],[1,0,1]]
示例 2:


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

提示:

m == matrix.length
n == matrix[0].length
1 <= m, n <= 200
-231 <= matrix[i][j] <= 231 - 1

answer:

Method 1: Use an extra array

This is the most intuitive method, that is, because the array is directly assigned to 0 when it encounters 0, it may make the original value that should not be 0 become 0, so we can use an array to store the original The number of rows and columns in the array is 0, and then when the original array is traversed, once it is found that one of its i or j is 0, it can be changed to 0.

Code:

void setZeroes(int** matrix, int matrixSize, int* matrixColSize){
    
    
    int m = matrixSize;
    int n =*matrixColSize;
    int row[m];
    int col[n];
    memset(row,0,sizeof(int)*m);
    memset(col,0,sizeof(int)*n);
    for(int i=0;i<m;i++)
    {
    
    
        for(int j=0;j<n;j++)
        {
    
    
            if(matrix[i][j]==0)
            {
    
    
                row[i] = 1;
                col[j] = 1;//找到对应要变为0的下标i与j
            }
        }
    }
    for(int i=0;i<m;i++)
    {
    
    
        for(int j=0;j<n;j++)
        {
    
    
            if(row[i]==1||col[j]==1)//找到了已经,所以开始遍历原数组是否有与其i或j相同的
            {
    
    
                matrix[i][j]=0;
            }
        }
    }
}

Method 2: No extra space is used, only two variables are used as markers

From the above method one, we only need one row and one column to mark the row and column labels that need to be replaced with 0, so we can directly use the first row and first column of the original array . But in this case, we will find that the original array will be destroyed . What is destroyed? What is the situation that we have abandoned? That is, if the first row or the first column has 0, we have ignored it , so we need to set up two variables to store whether the row and column are 0 , and then we can free the first row and first column. It can be used as the two arrays in our method 1, and finally according to the tag variable to determine whether to replace the first row and first column with 0.

Code:

void setZeroes(int** matrix, int matrixSize, int* matrixColSize){
    
    
    int temp1 = 1;
    int temp2 = 1;//因为第一行与第一列的元素其一个坐标已经确定好了,所以各自不需要两个i与j了,只要一个变量作为标志即可
    int m = matrixSize;
    int n = *matrixColSize;
    for(int i=0;i<m;i++)
    {
    
    
        if(matrix[i][0]==0)
        {
    
    
            temp1 = 0;
            break;
        }
    }
    for(int i=0;i<n;i++)
    {
    
    
        if(matrix[0][i]==0)
        {
    
    
            temp2 = 0;
            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(temp1==0)
    {
    
    
        for(int i=0;i<m;i++)
        {
    
    
            matrix[i][0]=0;
        }
    }
    if(temp2==0)
    {
    
    
        for(int i=0;i<n;i++)
        {
    
    
            matrix[0][i]=0;
        }
    }
}

Method 3: Use only one variable tag

If we set up a variable to store whether the first column has 0, then the first column is freed to be used as our " extra array ", so we start traversing from the second number in each row ( because the first number is treated as an " extra array " "Array" is used ), once they encounter 0, replace their corresponding matrix[0][j] and matrix[i][0] with 0. ( Here because they are originally due to the corresponding relationship will become 0, we Just make them better in advance so that they can be used as markers ).

After the traversal is complete, we will find that because we only set a variable to store whether there is 0 in the first column, and whether there is 0 in the first row, we did not store it, but we find that we are looking for why when we are performing the "filling" operation. Number, j why the number should be replaced with 0, the first row is traversed , that is, if the first row has 0, we have replaced the corresponding column element matrix[0][0] with 0. In this case, we will finally start from the bottom When we traverse the array again and replace it with 0, since matrix[0][0] will be used as the identification element of the first row we missed to help us mark whether this row has 0 , one variable can complete the operation.

Why does the last step of replacing 0 need to traverse from bottom to top ?
If we start from the first row, since the first row is not used in advance by us to store the value of 0 in a variable as in the second method, and it needs to be used as a characteristic element to replace the following elements , so it itself Make changes as late as possible.
And if the first line is replaced with 0 too early, we will find that many irrelevant 0s will appear. Because the first lineappears as a characteristic element .

Therefore, in fact, we do not need to use the variable to record whether there is 0 in the first row, because if the first row has 0, then the matrix [0] [0] is set to 0 in the first traversal, and in the second reverse When i=0 at the end of the traversal, the OR condition in if will judge that matrix [0] [0] is 0, and then update all the first rows to 0.

Code:

void setZeroes(int** matrix, int matrixSize, int* matrixColSize) {
    
    
    int m = matrixSize;
    int n = matrixColSize[0];
    int flag_col0 = false;//明确我们构建变量的目的是为了看第一行和第一列是否有0
    for (int i = 0; i < m; i++) 
    {
    
    
        if (!matrix[i][0]) {
    
    
            flag_col0 = true;//因为把两个步骤合一块了,但是还是要把应该先处理的放前面
        }
        for (int j = 1; j < n; j++) {
    
    
            if (!matrix[i][j]) {
    
    
                matrix[i][0] = matrix[0][j] = 0;
            }
        }
    }
    for (int i = m - 1; i >= 0; i--) 
    {
    
    //为了防止每一列的第一个元素被提前更新,我们需要从最后一行开始,倒序地处理矩阵元素
        for (int j = 1; j < n; j++) {
    
    
            if (!matrix[i][0] || !matrix[0][j]) {
    
    
                matrix[i][j] = 0;//不符合不会到
            }
        }
        if (flag_col0) {
    
    
            matrix[i][0] = 0;//把两个步骤放一块可以省去一些代码,也遵循原先的先后顺序
        }
    }
}

Guess you like

Origin blog.csdn.net/xiangguang_fight/article/details/115074217