Leet_code---73矩阵置零---C语言版

题目描述:

给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 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]
]

进阶:

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

题干分析:

  本题要求依旧比较简单,最粗暴的做法是将数组遍历,遇到0时将对应的行和列进行标记(这里不要用0标记,否则会判断失误);我们做进一步思考,发现并不需要反复对数组内所有元素进行标记,实际上我们只需要行和列的标记,至此解题思路就很明朗了;

思路分析:

  我们需要新两个的数组来存放标记,标记最好选用BOOL类型,这样轻松写意,其实这里的做法就是进阶中的空间O(m+n);常数空间的做法应该如何完成?我的思路是借用数组空间的第一行和第一列,但这里会在标记后置零时给你带来新的问题,你需要先判断除去行列首尾的三个点,然后将行列首尾三个点单独拿出来判断,可以采用标记单独标记:

 Leet_code---73矩阵置零---C语言版_第1张图片

  如果不将此三点单独拿出来讨论,会严重影响整个置零过程,可以结合图片思考一下;

  下图为空间O(m+n)因未选取此类方法,固将示意图贴出来

                             Leet_code---73矩阵置零---C语言版_第2张图片

到这里剩下的事情就是简单的递归循环了,其实了解思路后本题还是很简单的;

代码如下:(因为LETT_CODE中很多代码比我写的更加规范,固多有借鉴,侵删)

void setZeroes(int** matrix, int matrixRowSize, int matrixColSize) {
    bool firstRowZero = false, firstColZero = false;//行列标记
    int i, j;
    for (i = 0; i < matrixRowSize; ++i) {
        for (j = 0; j < matrixColSize; ++j) {
            if (i != 0 && j != 0 && matrix[i][j] == 0) {
                matrix[i][0] = 0;
                matrix[0][j] = 0;//在行列上直接标记
            } /*if*/else if (matrix[i][j] == 0) {
                if (i == 0)
                    firstRowZero = true;
                if (j == 0)
                    firstColZero = true;
            }//else if
        }//for-2
    }//for-1
    for (i = 1; i < matrixRowSize; ++i) {
        for (j = 1; j < matrixColSize; ++j) {
            if (matrix[i][0] == 0 || matrix[0][j] == 0)
                matrix[i][j] = 0;
        }//for-2
    }//for-1
    for (i = 0; firstColZero && i < matrixRowSize; ++i) {
        matrix[i][0] = 0;
    }//&&为短路判定,所以在这里不用担心多余的判定
    for (j = 0; firstRowZero && j < matrixColSize; ++j) {
        matrix[0][j] = 0;
    } return ;//void函数建议各位也写一下return,个人习惯问题
}


你可能感兴趣的:(Leet_code---73矩阵置零---C语言版)