leetcode刷题-73矩阵置零

166 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

leetcode73-矩阵置零

前文

本文为菜鸟的刷题记录,仅用作笔记使用,并非最佳解决方案。

题目信息

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

进阶:

一个直观的解决方案是使用  O(mn) 的额外空间,但这并不是一个好的解决方案。 一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。 你能想出一个仅使用常量空间的解决方案吗?

解题思路分析

解法1

很容易想到使用标记数组进行记录,先进行一次遍历,记录所有的位置是否为0.再进行二次遍历,如果数值是0,则对对应的行列进行置零操作。代码如下:

public void setZeroes(int[][] matrix) {
    int[] rows = new int[matrix.length];
    int[] columns;
    if(matrix.length > 0){
        columns = new int[matrix[0].length];
    }else{
        columns = new int[0];
    }
    for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
            if(matrix[i][j] == 0){
                rows[i] = 1;
                columns[j] = 1;
            }
        }
    }

    for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
            if(rows[i] == 1 || columns[j] == 1){
                matrix[i][j] = 0;
            }
        }
    }
}

解法2

解法2主要是对于空间复杂度的降低。利用数组的第一行第一列作为标记列。首先采用数组的第一行、第一列作为记录。遍历后续的数据,如果为0则将第一行、第一列进行对应标记。二次遍历时再将对应的行列进行处理。要注意首先要记录一下原始记录第一行、第一列是否有0,如果有需要把第一行、第一列置为0.代码如下:

public void setZeroes(int[][] matrix) {
//        记录最开始是否为0
        boolean row = false;
        boolean column = false;
        for (int i = 0; i < matrix.length; i++) {
            if(matrix[i][0] == 0){
                column = true;
            }
        }

        if(matrix.length > 0){
            for (int i = 0; i < matrix[0].length; i++) {
                if(matrix[0][i] == 0){
                    row = true;
                }
            }
        }
//        标记遍历
        for (int i = 1; i < matrix.length; i++) {
            for (int j = 1; j < matrix[0].length; j++) {
                if(matrix[i][j] == 0){
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                }
            }
        }
//        处理
        for (int i = 1; i < matrix.length; i++) {
            for (int j = 1; j < matrix[0].length; j++) {
                if(matrix[i][0] == 0 || matrix[0][j] == 0){
                    matrix[i][j] = 0;
                }
            }
        }
//        处理如果最开始就是0的情况
        if(row){
            for (int i = 0; i < matrix[0].length; i++) {
                matrix[0][i] = 0;
            }
        }
        if(column){
            for (int i = 0; i < matrix.length; i++) {
                matrix[i][0] = 0;
            }
        }
    }

复杂度分析

  • 时间复杂度 o(m*n)
  • 空间复杂度 o(m*n) o(1)

后记

  • 千古兴亡多少事?悠悠。不尽长江滚滚流。