LeetCode 01.08 零矩阵(中等) | Java 刷题打卡

204 阅读2分钟

本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接

题目描述

零矩阵

编写一种算法,若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]
]

思路分析

首先来个最简单的解法,就是暴力破解,用一个该List<int[]> list将对于矩阵位置的为 0 的下标都记录下来,然后再遍历矩阵中的值,对行和列分别进行置 0,该解法的时间复杂度是O(mn){O(m*n)},空间复杂度也是O(m){O(m)}O(n){O(n)}

还有一种解法是,整个矩阵总归是行和列是否有 0 ,我们可以统一移植到首行和首列。我们先判断首行和首列是否有 0,利用两个变量进行记录,该解法的时间复杂度是O(mn){O(m*n)},空间复杂度也是O(1){O(1)}

代码展示

解法一:暴力破解,先将矩阵中为 0 的坐标都记录下来,最后再遍历,将对应的位置置为 0。时间复杂度是O(mn){O(m*n)},空间复杂度是O(m){O(m)}O(n){O(n)}

    public void setZeroes(int[][] matrix) {
        List<int[]> list = new ArrayList<>();
        for (int i = 0; i < matrix.length; i++) { //matrix.length = 4
            for (int j = 0;j < matrix[0].length;j++){
                if (matrix[i][j] == 0){
                    list.add(new int[]{i,j});
                }
            }
        }
        for (int i = 0;i < list.size();i++){
            int[] temp = list.get(i);
            int a1 = temp[0];
            for (int j = 0;j < matrix[0].length;j++){
                matrix[a1][j] = 0;
            }
            int a2 = temp[1];
            for (int k = 0;k < matrix.length;k++){
                matrix[k][a2] = 0;
            }
        }

解法二:上面解法的时间复杂度是O(mn){O(m*n)},空间复杂度是O(m){O(m)}O(n){O(n)},时间复杂度肯定是不能简化,因为需要都遍历下来,但是空间复杂度是可以优化的,因为我们都可以移植到第一行第一列,但是首先要先记住第一行/列是否有 0,然后再进行处理。

     public void setZeroes(int[][] matrix) {  
				int m = matrix.length;
        int n = matrix[0].length;
        boolean firstCol = false; //列
        boolean firstRow = false; //行
        for (int i = 0; i < m; i++) {
            if (matrix[i][0] == 0) {
                firstCol = true; //第一列有0
                break;
            }
        }
        for (int j = 0; j < n; j++) {
            if (matrix[0][j] == 0) {
                firstRow = true; //第一行有0
                break;
            }
        }

        for (int i = 1; i < m; i++) { //给第一行或这一列赋值为0
            for (int j = 1; j < n; j++) {
                if (matrix[i][j] == 0) {
                    matrix[i][0] = matrix[0][j] = 0;
                }
            }
        }
        for (int i = 1; i < m; i++) { //列
            for (int j = 1; j < n; j++) { //行
                if (matrix[i][0] == 0 || matrix[0][j] == 0){
                    matrix[i][j] = 0;
                }
            }
        }
        if (firstRow){
            for (int i = 0;i < n;i++){
                matrix[0][i] = 0;
            }
        }
        
        if (firstCol){
            for (int j = 0;j < m;j++){
                matrix[j][0] = 0;
            }
        }
     }

总结

在解答该类题目时,首先可以尝试暴力破解,然后在结合矩阵和题目的特点,对空间复杂度进行优化。