数组——矩阵清零

题目描述

给定一个矩阵,如果有零元素那么就将零元素所在的行和列都置为零。

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


题目的难点就在于,如果遇到零元素之后马上在矩阵上操作,将所在的行和列都置为零。在接下来的遍历中,如果你再遇到零,你讲不清楚是原矩阵的零还是你修改之后的零。所以,一种方法就是先通过两个数组来记录该行该列上有没有零元素,等对矩阵遍历完之后再统一修改即可

方法一:新开辟两个数组,记录每行和每列是否存在 0,空间复杂度为(m+n)

public class Solution {
    public void setZeroes(int[][] matrix) {
        if(matrix == null||matrix.length == 0||matrix[0].length == 0)
            return;
        boolean[] row=new boolean[matrix.length];
        boolean[] col=new boolean[matrix[0].length];
        //遍历matrix一次,记录有0的行和列
        for(int i=0;i<matrix.length;i++)
            {
            for(int j=0;j<matrix[i].length;j++)
                {
                if(matrix[i][j] == 0)
                    {
                    row[i]=true;
                    col[j]=true;
                }
            }
        }
        //将有0的行清零
        for(int i=0;i<row.length;i++)
            {
            if(row[i] == true)
                {
                for(int m=0;m<matrix[0].length;m++)
                    {
                    matrix[i][m]=0;
                }
            }
        }
        //将有0的列清零
         for(int j=0;j<col.length;j++)
            {
            if(col[j] == true)
                {
                for(int n=0;n<matrix.length;n++)
                    {
                    matrix[n][j]=0;
                }
            }
        }
   }
}
方法二:对方法一的改进,利用matrix中的空间

如果matrix中有一个0,那么该row,col的行和列都为0,那么之后该行和列就能用来存储解法二的行列了。空降O(1)
matrix[row][k]用来存储第k列是否有0
matrix[k][col]用来存储第k行是否有0

public class Solution {
    public void setZeroes(int[][] matrix) {
        if(matrix == null||matrix.length == 0||matrix[0].length == 0)
            return;
       boolean firstzero=false;
        int row=0;
        int col=0;
        //遍历matrix一次,找到第一个0的位置
        for(int i=0;i<matrix.length;i++)
            {
            for(int j=0;j<matrix[i].length;j++)
                {
                
                if(matrix[i][j] == 0)
                    {
                    row=i;
                    col=j;
                    firstzero=true;
                    break;
                }
            }
        }
        if(firstzero == false)
            return;
        //遍历matrix,记录有0的行和列
         for(int i=0;i<matrix.length;i++)
            {
            for(int j=0;j<matrix[i].length;j++)
                {
                if(matrix[i][j] == 0&&i!=row&&j!=col)
                    {
                    matrix[row][j]=0;
                    matrix[i][col]=0;
                }
            }
        }
       //遍历matrix,清0  注意:这里不用逐行逐列清0,要不会变得比较复杂。
         for(int i=0;i<matrix.length;i++)
            {
            for(int j=0;j<matrix[i].length;j++)
                {
                if(i!=row&&j!=col)
                if(matrix[i][col] == 0||matrix[row][j] == 0)
                    {
                   matrix[i][j]=0;
                }
            }
        }
        //将row,col行列清0
        for(int i=0;i<matrix.length;i++)
            {
            matrix[i][col]=0;
        }
        for(int j=0;j<matrix[row].length;j++)
            {
            matrix[row][j]=0;
        }
   }
}


### LeetCode 上使用 C 语言处理二维数组的相关问题与解法 在 LeetCode 中,涉及二维数组的问题通常会测试编程者对矩阵操作的理解以及优化算法的能力。以下是针对 C 语言实现二维数组相关问题的一个典型例子及其解决方案。 #### 示例题目:设置零矩阵 给定一个 `m x n` 的矩阵,如果某个元素为 0,则将其所在的行和列的所有元素都设为 0。此问题可以通过额外的空间来解决,也可以通过原地标记的方式减少空间复杂度。 ##### 方法一:使用辅助数组标记行列 这种方法利用两个辅助数组分别记录哪些行和列需要被置零。其时间复杂度为 \(O(m \times n)\),而空间复杂度为 \(O(m + n)\)[^1]。 ```c void setZeroes(int** matrix, int matrixSize, int* matrixColSize){ int m = matrixSize; int n = *matrixColSize; bool* row = (bool*)calloc(m, sizeof(bool)); bool* col = (bool*)calloc(n, sizeof(bool)); // 记录需要清零的行和列 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) { for (int j = 0; j < n; ++j) { if (row[i] || col[j]) { matrix[i][j] = 0; } } } free(row); free(col); } ``` 上述方法虽然简单易懂,但由于引入了额外的存储开销,在某些情况下可能不满足最优解的要求。 ##### 方法二:原地修改策略 为了进一步降低空间复杂度至常量级别 (\(O(1)\)),可以采用一种更巧妙的方法——利用矩阵的第一行和第一列表示其他位置的状态标志位[^3]。 具体做法如下: - 使用第一个单元格作为特殊状态指示器; - 如果某行/列存在零值,则将对应首元标注为真(true); - 最后再依据这些标记完成最终更新过程即可。 由于该方案无需开辟新的内存区域保存中间数据结构,因此极大地节省了资源消耗。 --- ### § 相关问题 § 1. 如何用动态规划求解编辑距离? 2. 在二维网格中寻找路径有哪些常见技巧? 3. 基于双指针技术如何高效移除指定数值元素? 4. 对于含有重复项的大规模整型序列,怎样快速定位目标值的位置区间? 5. 实现一个函数判断输入字符串能否由另一个字符串重新排列组成回文串形式吗 ?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值