Likou 73. Puesta a cero matricial --- solución de tres métodos (use espacio adicional, use dos variables, use una variable)

73. Matriz de puesta a cero

Dada una matriz mxn, si un elemento es 0, establezca todos los elementos en su fila y columna en 0. Utilice el algoritmo in situ.

Avanzado:

Una solución intuitiva es utilizar O (mn) espacio extra, pero esta no es una buena solución.
Una simple mejora es utilizar O (m + n) espacio extra, pero esta todavía no es la mejor solución.
¿Puedes pensar en una solución que use solo espacio constante?

示例 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

respuesta:

Método 1: use una matriz adicional

Este es el método más intuitivo, es decir, debido a que la matriz se asigna directamente a 0 cuando encuentra 0, puede hacer que el valor original que no debería ser 0 se convierta en 0, por lo que podemos usar una matriz para almacenar el número original de filas y columnas en la matriz es 0, y luego, cuando se atraviesa la matriz original, una vez que se encuentra que una de sus i o j es 0, se puede cambiar a 0.

Código:

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;
            }
        }
    }
}

Método 2: No se usa espacio adicional, solo se usan dos variables como marcadores

Del método anterior uno, solo necesitamos una fila y una columna para marcar las etiquetas de fila y columna que deben reemplazarse con 0, por lo que podemos usar directamente la primera fila y la primera columna de la matriz original . Pero en este caso, encontraremos que la matriz original se destruirá . ¿Qué se destruye? ¿Cuál es la situación que hemos abandonado? Es decir, si la primera fila o la primera columna tiene 0, se han ignorado , por lo que tenemos que configurar dos variables para almacenar si la fila y la columna son 0 , y entonces podemos liberar la primera fila y la primera columna. Se se puede usar como las dos matrices en nuestro método 1 y, finalmente, de acuerdo con la variable de etiqueta para determinar si se reemplaza la primera fila y la primera columna con 0.

Código:

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;
        }
    }
}

Método 3: use solo una etiqueta de variable

Si configuramos una variable para almacenar si la primera columna tiene 0, entonces la primera columna se libera para usarse como nuestra " matriz adicional ", por lo que comenzamos a recorrer desde el segundo número en cada fila ( porque el primer número se trata como se usa una " matriz adicional " "matriz" ), una vez que encuentran 0, reemplace su matriz correspondiente [0] [j] y la matriz [i] [0] con 0. ( Aquí, debido a que originalmente se deben a la relación correspondiente, se convierten en 0, simplemente los mejoramos de antemano para que puedan usarse como marcadores ).

Después de que se complete el recorrido, encontraremos que debido a que solo configuramos una variable para almacenar si hay 0 en la primera columna, y si hay 0 en la primera fila, no lo almacenamos, pero encontramos que estamos buscando por qué cuando estamos realizando la operación de "llenado". Número, j por qué el número debe reemplazarse con 0, la primera fila se recorre , es decir, si la primera fila tiene 0, hemos reemplazado la matriz de elementos de columna correspondiente [0 ] [0] con 0. En este caso, finalmente comenzaremos desde abajo. Cuando recorramos la matriz nuevamente y la reemplacemos con 0, ya que la matriz [0] [0] se usará como el elemento de identificación de la primera fila que perdido para ayudarnos a marcar si esta fila tiene 0 , una variable puede completar la operación.

¿Por qué el último paso para reemplazar 0 debe recorrer de abajo hacia arriba ?
Si partimos de la primera fila, ya que la primera fila no la usamos de antemano para almacenar el valor de 0 en una variable como en el Método 2, y debe usarse como un elemento de característica para reemplazar los siguientes elementos , entonces es en sí mismo Realizar cambios lo más tarde posible.
Y si la primera línea se reemplaza con 0 demasiado pronto, encontraremos que aparecerán muchos 0 irrelevantes. Porque la primera líneaaparece como elemento característico .

Por lo tanto, de hecho, no necesitamos usar la variable para registrar si hay 0 en la primera fila, porque si la primera fila tiene 0, entonces la matriz [0] [0] se establece en 0 en el primer recorrido, y en el segundo reverso Cuando i = 0 al final del recorrido, la condición OR en if juzgará que la matriz [0] [0] es 0, y luego actualizará todas las primeras filas a 0.

Código:

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;//把两个步骤放一块可以省去一些代码,也遵循原先的先后顺序
        }
    }
}

Supongo que te gusta

Origin blog.csdn.net/xiangguang_fight/article/details/115074217
Recomendado
Clasificación