• [leetcode]Set Matrix Zeroes


    Set Matrix Zeroes

    Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.

    Follow up:

    Did you use extra space?
    A straight forward solution using O(mn) space is probably a bad idea.
    A simple improvement uses O(m + n) space, but still not the best solution.
    Could you devise a constant space solution?

    这道题前天实验室同学问过我,今天简单整理一下四种空间复杂度的解法,时间复杂度肯定是一样的O(mn)

    算法:

    思路1. 空间复杂度O(mn)

    开辟O(m*n)空间tag,标记matrix中每个0的位置,全部标记完之后,再遍历tag,将matrix相关行列赋0

     1 public class Solution {
     2 public void setZeroes(int[][] matrix) {
     3         if(matrix == null || matrix.length == 0) return;
     4         int height = matrix.length;
     5         int width = matrix[0].length;
     6         boolean[][] tag = new boolean[height][width];
     7         for(int i = 0; i < height; i++){
     8             for(int j = 0; j < width; j++){
     9                 if(matrix[i][j] == 0)
    10                     tag[i][j] = true;
    11             }
    12         }
    13         for(int i = 0; i < height; i++){
    14             for(int j = 0; j < width; j++){
    15                 if(tag[i][j]){
    16                     setZero(matrix, height, width, i, j);
    17                 }
    18             }
    19         }
    20     }
    21     private void setZero(int[][] matrix,int height,int width,int row,int column){
    22         for(int i = 0; i < height; matrix[i++][column] = 0);
    23         for(int i = 0; i < width; matrix[row][i++] = 0);
    24     }
    25 }
    View Code

    思路2. 空间复杂度O(m+n)

    因为题中要求某行只要有0,即将该行全部置0,因此,我们无须关心该行的0出现在哪一列。同理,列一样一样处理。

     1 public class Solution {
     2 public void setZeroes(int[][] matrix) {
     3         if(matrix == null || matrix.length == 0) return;
     4         int height = matrix.length;
     5         int width = matrix[0].length;
     6         Set<Integer> rowSet = new HashSet<Integer>();
     7         Set<Integer> columnSet = new HashSet<Integer>();
     8         for(int i = 0; i < height; i++){
     9             for(int j = 0; j < width; j++){
    10                 if(matrix[i][j] == 0){
    11                     rowSet.add(i);
    12                     columnSet.add(j);
    13                 }
    14             }
    15         }
    16         for(int row : rowSet){
    17             for(int i = 0; i < width; matrix[row][i++] = 0);
    18         }
    19         for(int column : columnSet){
    20             for(int i = 0; i < height; matrix[i++][column] = 0);
    21         }
    22         }
    23 }    
    View Code

    思路3. 空间复杂度O(m)或者O(n)

    在扫描每一行的时候,用一个Boolean值标记该行是否含0,(如果含有0)并将0的列号记录下来(columnSet),该行扫描结束时,将该行全部置0,matrix扫描完之后进行列的统一处理。

     1 public class Solution {
     2     public void setZeroes(int[][] matrix) {
     3         if(matrix == null || matrix.length == 0) return;
     4         int height = matrix.length;
     5         int width = matrix[0].length;
     6         boolean hasZero = false;
     7         Set<Integer> columnSet = new HashSet<Integer>();
     8         for(int i = 0; i < height; i++){
     9             hasZero = false;
    10             for(int j = 0; j < width; j++){
    11                 if(matrix[i][j] == 0){
    12                     hasZero = true;
    13                     columnSet.add(j);
    14                 }
    15             }
    16             if(hasZero) 
    17                 for(int j = 0; j < width; matrix[i][j++] = 0);
    18         }
    19         for(int column : columnSet){
    20             for(int i = 0; i < height; matrix[i++][column] = 0);
    21         }
    22     }
    23 }
    View Code

    思路4. 空间复杂度O(1)

    这个思路是在思路3的基础上做了优化,将本应记录在columnSet的列号,记录在第1行中的相应列(其他行也可以,但是稍有区别,大家可以想一下)

     1 public class Solution {
     2     public void setZeroes(int[][] matrix) {
     3         if(matrix == null || matrix.length == 0) return;
     4         int height = matrix.length;
     5         int width = matrix[0].length;
     6         boolean hasZeroInFirstRow = false;
     7         for(int j = 0; j < width; j++){
     8             if(matrix[0][j] == 0)
     9                 hasZeroInFirstRow = true;
    10         }
    11         for(int i = 1; i < height; i++){
    12             boolean hasZero = false;
    13             for(int j = 0; j < width; j++){
    14                 if(matrix[i][j] == 0){
    15                     hasZero = true;
    16                     matrix[0][j] = 0;
    17                 }
    18             }
    19             if(hasZero)
    20                 for(int j = 0; j < width; matrix[i][j++] = 0);
    21         }
    22         for(int j = 0; j < width; j++){
    23             if(matrix[0][j] == 0){
    24                 for(int i = 0; i < height; matrix[i++][j] = 0);
    25             }
    26         }
    27         if(hasZeroInFirstRow)
    28             for(int j = 0; j < width; matrix[0][j++] = 0);
    29     }
    30 }
    View Code

    以上四种算法的时间复杂度都是O(m*n),空间复杂度从O(m*n)到O(1),可能代码写的不够简洁,但是可读性应该还好吧,哈哈。FYI

  • 相关阅读:
    一次linux启动故障记录
    linux 时间相关的一些总结
    linux 3.10 gro的理解和改进
    linux 3.10 的中断收包笔记
    一个有趣的nginx问题引发的小问题
    linux 3.10 tcp的accept测试
    linux mce的一些相关内容和用户态监控的设计方法
    C/C++(基础-运算符详解)
    C/C++(基础-常量,类型转换)
    C/C++(基础编码-补码详解)
  • 原文地址:https://www.cnblogs.com/huntfor/p/3851505.html
Copyright © 2020-2023  润新知