73.矩阵置零

题目描述

请添加图片描述

分析

若直接在遍历数组的过程中修改,会分不清后续的0是修改后的还是原来就存在的。

所以需要用额外的空间来存储原来的数组中是否存在0,且区分各算法的优异性

两个额外数组

描述

用两个标记数组来记录每一行和每一列是否有0出现(用来更新矩阵)。接着遍历一次矩阵,根据这两个标记数组来进行更新。

代码

void setZeroes(int** matrix, int matrixSize, int* matrixColSize){
    int m = matrixSize, n = matrixColSize[0];
    int row[m], column[n];
    int i, j;
    for (i = 0; i < m;i++){
        row[i] = 0;
    }
    for (j = 0; j < n;j++){
        column[j] = 0;
    }
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
        {
            if (matrix[i][j] == 0)
            {
                row[i] = 1;
                column[j] = 1;
            }
        }
    }
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
        {
            if (row[i]==1||column[j]==1)
            {
                matrix[i][j] = 0;
            }
        }
    }
}

利用原矩阵空间进行存储

描述

利用原矩阵空间的第一行和第一列来代替额外数组进行存储。并只需要利用两个整型变量来储存原来第一行/列是否有0元素,最后再根据这两个整型变量来更新数组的第一行/列。

代码

void setZeroes(int** matrix, int matrixSize, int* matrixColSize){
    int row1 = 0, column1 = 0;
    int m = matrixSize, n = matrixColSize[0];
    int i, j;
    for (i = 0; i < m;i++){//记录第一列是否有0
        if(matrix[i][0]==0){
            column1 = 1;
        }
    }
    for (j = 0; j < n;j++){//记录第一行是否有0
        if(matrix[0][j]==0){
            row1 = 1;
        }
    }
    //将第一行和第一列用于储存此列/行是否有0,若有将其置为0
    for (i = 1; i < m;i++){
        for (j = 1; j < n;j++){
            if(matrix[i][j] == 0){
                matrix[0][j] = 0;
                matrix[i][0] = 0;
            }
        }
    }
    for (i = 1; i < m;i++){
        for (j = 1; j < n;j++){
            if(matrix[0][j] == 0||matrix[i][0]==0){
                matrix[i][j] = 0;
            }
        }
    }
    //处理第一行和第一列
    if(row1==1){
        for(j = 0; j < n;j++){
            matrix[0][j] = 0;
        }
    }
    if(column1==1){
        for (i = 0; i < m;i++){
            matrix[i][0] = 0;
        }
    }
}

第二种算法的优化

描述

注意到第二种算法没有利用到数组的[0][0]元素进行存储,因此改进后对其加以利用,

代码

void setZeroes(int** matrix, int matrixSize, int* matrixColSize){
    int column1 = 0;
    int m = matrixSize, n = matrixColSize[0];
    int i, j;
    for (i = 0; i < m;i++){//记录第一列是否有0
        if(matrix[i][0]==0){
            column1 = 1;
        }
    }
    for (j = 0; j < n;j++){//记录第一行是否有0
        if(matrix[0][j]==0){
            matrix[0][0] = 0;//储存在[0][0]中
        }
    }
    //将第一行和第一列用于储存此列/行是否有0,若有将其置为0
    for (i = 1; i < m;i++){
        for (j = 1; j < n;j++){
            if(matrix[i][j] == 0){
                matrix[0][j] = 0;
                matrix[i][0] = 0;
            }
        }
    }
    for (i = 1; i < m;i++){
        for (j = 1; j < n;j++){
            if(matrix[0][j] == 0||matrix[i][0]==0){
                matrix[i][j] = 0;
            }
        }
    }
    //处理第一行和第一列
    if(matrix[0][0]==0){
        for(j = 0; j < n;j++){
            matrix[0][j] = 0;
        }
    }
    if(column1==1){
        for (i = 0; i < m;i++){
            matrix[i][0] = 0;
        }
    }
}

收获

原地算法

对于原地算法,为了不改变原值,一般需要另外声明变量申请空间来对原值进行记忆。
当然,额外空间越少越好,因此可参照本题的做法利用原空间进行存储,并利用算法规避数据覆盖带来的麻烦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值