题目:
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.(Medium)
分析:
题意很简单,就是把为0的元素所在的行和列都置0;
首先不能直接边循环边做,这样会造成很多本来不是0的元素被置0之后,在后续判断中将它的行列也置0;
所以简单的方法是建立两个数组,存行和列是否为0的情况,遍历一遍更新两个数组,再遍历一遍把应该置0的全部置0。
自己写的时候先考虑用了个set便于不记录重复的下标,所以有如下代码1:
1 class Solution { 2 public: 3 void setZeroes(vector<vector<int>>& matrix) { 4 set<int> rowflag; 5 set<int> colomnflag; 6 for (int i = 0; i < matrix.size(); ++i) { 7 for (int j = 0; j < matrix[0].size(); ++j) { 8 if (matrix[i][j] == 0) { 9 rowflag.insert(i); 10 colomnflag.insert(j); 11 } 12 } 13 } 14 for (auto i : rowflag) { 15 for (int j = 0; j < matrix[0].size(); ++j) { 16 matrix[i][j] = 0; 17 } 18 } 19 for (auto i : colomnflag) { 20 for (int j = 0; j < matrix.size(); ++j) { 21 matrix[j][i] = 0; 22 } 23 } 24 return; 25 } 26 };
程序还算简洁,记录最坏情况那里空间复杂度是为的O(nlogn + mlogm);
记录bool数组的方式,自己开始觉得写起来不够简洁。
后来看了讨论区大家的写法,发现第二次的用循环一遍,然后rowflag[i] || colonmnflag[j]可以很简洁的写出来,所以有如下代码2:
1 class Solution { 2 public: 3 void setZeroes(vector<vector<int>>& matrix) { 4 int rowflag[matrix.size()] = {0}; 5 int colomnflag[matrix[0].size()] = {0}; 6 for (int i = 0; i < matrix.size(); ++i) { 7 for (int j = 0; j < matrix[0].size(); ++j) { 8 if (matrix[i][j] == 0) { 9 rowflag[i] = 1; 10 colomnflag[j] = 1; 11 } 12 } 13 } 14 for (int i = 0; i < matrix.size(); ++i) { 15 for (int j = 0; j < matrix[0].size(); ++j) { 16 if (rowflag[i] == 1 || colomnflag[j] == 1) { 17 matrix[i][j] = 0; 18 } 19 } 20 } 21 return; 22 } 23 };
题目的follow-up中问道能否用常数的空间解决该问题,做法就是用两个变量记录第一行和第一列是否有0,
然后用第一行和第一列充当rowflag,colomnflag即可。