程序员面试金典 面试题 01.08.零矩阵

该篇博客讨论了一种高效的算法,用于处理二维矩阵中遇到0元素时,将对应行和列清零的问题。提供了两种Java实现,一种逐个标记法,另一种单行标记法,都在O(1)额外空间复杂度下完成,并且在所有Java提交中取得了优秀的执行时间和内存消耗成绩。
摘要由CSDN通过智能技术生成

面试题 01.08.零矩阵

题目描述

编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。

示例1

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

示例2

输入:
[
[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。
  • 你能只用额外的O(N)空间而不是O(N2)吗?在为0的单元格列表中你真正需要的是什么信息?
  • 你可能需要一些数据存储来维护一个需要清零的行与列的列表。通过使用矩阵本身来存储数据,你是否可以把额外的空间占用减小到O(1)?

示例代码
Java 逐个标记

public class Question01_08 {
    public static void main(String[] args) {
        Solution s = new Solution();
        int[][] matrix01 = {
                {1,1,1},
                {1,0,1},
                {1,1,1}
        };
        s.setZeroes(matrix01);
        for (int i = 0; i < matrix01.length; i++) {
            for (int j = 0; j < matrix01.length; j++) {
                System.out.print(matrix01[i][j]);
            }
            System.out.println();
        }
        int[][] matrix02 = {
                {0,1,2,0},
                {3,4,5,2},
                {1,3,1,5}
        };
        s.setZeroes(matrix02);
        for (int i = 0; i < matrix02.length; i++) {
            for (int j = 0; j < matrix02[0].length; j++) {
                System.out.print(matrix02[i][j]);
            }
            System.out.println();
        }
    }
}

class Solution{
    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;
            }
        }
    }
}

Java 提交结果
执行用时:1 ms, 在所有 Java 提交中击败了99.84% 的用户
内存消耗:39.6 MB, 在所有 Java 提交中击败了95.27% 的用户

示例代码
Java 单行标记

public class Question01_08 {
    public static void main(String[] args) {
        Solution s = new Solution();
        int[][] matrix01 = {
                {1,1,1},
                {1,0,1},
                {1,1,1}
        };
        s.setZeroes(matrix01);
        for (int i = 0; i < matrix01.length; i++) {
            for (int j = 0; j < matrix01.length; j++) {
                System.out.print(matrix01[i][j]);
            }
            System.out.println();
        }
        int[][] matrix02 = {
                {0,1,2,0},
                {3,4,5,2},
                {1,3,1,5}
        };
        s.setZeroes(matrix02);
        for (int i = 0; i < matrix02.length; i++) {
            for (int j = 0; j < matrix02[0].length; j++) {
                System.out.print(matrix02[i][j]);
            }
            System.out.println();
        }
    }
}

class Solution{
    public void setZeroes(int[][] matrix){
        int M = matrix.length,N = matrix[0].length;
        boolean flag = false;
        for (int i = 0; i < M; i++) {
            if(matrix[i][0] == 0)
                flag = true;
            for (int j = 1; j < N; j++) {
                if( matrix[i][j] == 0 )
                    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] == 0 || matrix[0][j] == 0)
                    matrix[i][j] = 0;
            }
            if(flag)
                matrix[i][0] = 0;
        }
    }
}

Java 提交结果
执行用时:1 ms, 在所有 Java 提交中击败了99.84% 的用户
内存消耗:39.2 MB, 在所有 Java 提交中击败了99.88% 的用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

W.Lionel.Esaka

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值