leetcode 学习之路

题目描述

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。

在这里插入图片描述

输入:matrix = [[1,1,1],[1,0,1],[1,1,1]]
输出:[[1,0,1],[0,0,0],[1,0,1]]

在这里插入图片描述

输入: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]]

一、算法描述

  矩阵中为0的元素其上下左右四个方向的元素都要置0。首先我想到的算法就是找出矩阵中为0的元素做出标记,然后对做标记的元素向其上下左右四个方向进行深度优先遍历,将遍历到的元素标记为0。但是这样的空间复杂度为 O ( n m ) O(nm) O(nm)。也就是说需要借助一个n*m的标志位数组来记录数组中的每一位数值。同时这种深度遍历会导致重复访问的情况,如下图所示: 第一行元素被访问两次。
在这里插入图片描述
  一种改进的方式是分别记录数组中0元素的行标和列标,当再次遍历数组,该元素的行标或者列表与0元素对应时就将其标志为0。如下图所示:
在这里插入图片描述

二、JAVA实现

1.深度遍历

public void setZeroes(int[][] matrix) {
        int rowLength=matrix.length;
        int colLenght=matrix[0].length;
        boolean[][] flag=new boolean[rowLength][colLenght];
        for (int i=0;i<rowLength;i++){
            for (int j=0;j<colLenght;j++){
                if (matrix[i][j]==0){
                    flag[i][j]=true;
                }
            }
        }
        for (int i=0;i<rowLength;i++){
            for (int j=0;j<colLenght;j++){
                if (matrix[i][j]==0&&flag[i][j]){
                    dfsL(matrix,i,j-1);
                    dfsR(matrix,i,j+1);
                    dfsU(matrix,i-1,j);
                    dfsD(matrix,i+1,j);
                }
            }
        }

    }
    public void dfsL(int[][] matrix,int i,int j){
        if (j<0)
            return;
        matrix[i][j]=0;
        dfsL(matrix,i,j-1);
    }
    public void dfsR(int[][] matrix,int i,int j){
        if (j>=matrix[0].length)
            return;
        matrix[i][j]=0;
        dfsR(matrix,i,j+1);
    }
    public void dfsU(int[][] matrix,int i,int j){
        if (i<0)
            return;
        matrix[i][j]=0;
        dfsU(matrix,i-1,j);
    }
    public void dfsD(int[][] matrix,int i,int j){
        if (i>= matrix.length)
            return;
        matrix[i][j]=0;
        dfsD(matrix,i+1,j);
    }


2.双数组

public void setZeroes(int[][] matrix) {
       int m = matrix.length, n = matrix[0].length;
       boolean[] row = new boolean[m];
       boolean[] col = new boolean[n];
       for(int i = 0; i < m; i++){
           for(int j = 0; j < n; j++){
               if(matrix[i][j] == 0){
                   row[i] = 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;
               }
           }
       }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值