Leetcode.面试题 01.08. Zero Matrix LCCI题解

Posted martinlwx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode.面试题 01.08. Zero Matrix LCCI题解相关的知识,希望对你有一定的参考价值。

  • ??:为什么不能直接扫描一边的时候清零?

    • ??:会搞混“修改产生的0”和“矩阵中原有的0”,遍历的后面可能会把你前面修改的0当成矩阵原有的0
  • 方法一:开辟一个矩阵标记要置0的位置,空间复杂度为(O(mn))。代码略。

  • 方法二:事实上我们开辟的标记矩阵中存在很大的空间浪费,我们标记的时候关心的是行坐标和列坐标[i,j],由此我们可以想到开一个边表row_set和一个列表column_set,这样的空间复杂度就是(O(m+n))。代码略。

  • 方法三

    • 其实我一开始看到(O(1))的要求,脑海里的想法是用一个特殊的int值来表示0,不过这太不严谨了
    • 问题的核心是如何区分“修改产生的0”和“矩阵中原有的0”。在方法二的基础上延申以及题目题目用常数级别的(O(1))空间的要求,我们可以想到要是能够用原来数组中的某行某列来当作row_setcolumn_set就好了。
    • 综合来考虑,我们最好的选择是第一行第一列,采用第一行第一列的原因是——因为是“十字形”(沿行沿列)置0,那么我们总会到最边缘的第一行和第一列置0。而只修改第一行第一列而不动路径上的其他位置,就不会在遍历的时候搞混“标记产生的0”和“矩阵中原有的0”
    • 第二遍扫描除了第一行第一列的子矩阵,对每个位置matrix[i][j]检查第一行和第一列对应的标记matrix[i][0] == 0 || matrix[0][j] == 0 ?,如果是,我们就把当前位置置0
    • 采用第一行第一列的方式还会有个问题——a[0][0]意思是标记为第一行为0还是第一列为0,两种都可以,但只能选一个。所以我们还要再设置一个bool变量,表示另一种情况。
  • 举个例子

[
	[1,3,4,7],
	[3,5,0,8],
	[7,8,9,5],
	[5,0,4,6]
]

[
	[1,0,0,7],
	[0,5,0,8],
	[7,8,9,5],
	[0,0,4,6]
]	//此时修改完了第一行和第一列的

[
	[5,0,8],
	[8,9,5],
	[0,4,6]
]	//这就是我们第二遍遍历要看的子矩阵,此时对于每个matrix[i][j],我们再检查第一行和第一列对应的位置有没有为0的即可。
//之后再单独处理行和列即可
代码
class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        bool is_col = false;	//此处我们让matrix[0][0]为行的标记,所以开了个标记列的bool变量
        int row = matrix.size();
        int column = matrix[0].size();

        for(int i=0;i<row;i++){
            if(matrix[i][0] == 0)   is_col = true;  //只要第一列有0,那么最后我们肯定要对第一列进行赋值为0的操作
            for(int j=1;j<column;j++)
                if(matrix[i][j] == 0){
                    matrix[0][j] = 0;
                    matrix[i][0] = 0;
                }   //标记行头、列头
        }

        for(int i=1;i<row;i++)
            for(int j=1;j<column;j++)
                if(matrix[i][0] == 0 || matrix[0][j] == 0)
                    matrix[i][j] = 0;
        
        if(matrix[0][0] == 0)
            for(int j=1;j<column;j++)
                matrix[0][j] = 0;   
        if(is_col)  //第一列为0
            for(int i=0;i<row;i++)
                matrix[i][0] = 0;
    }
};

以上是关于Leetcode.面试题 01.08. Zero Matrix LCCI题解的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 1624. 两个相同字符之间的最长子字符串 / 698. 划分为k个相等的子集 / 面试题 01.08. 零矩阵 / 1694. 重新格式化电话号码

Linux系统中有关/dev/null和/dev/zero文件说明及实践

[ 剑指offer ] 面试题对应的LeetCode

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

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

LeetCode 面试题63. 股票的最大利润