class Solution {
public:
// 将Mat 第cur 列设为0
void processMat(vector<vector<int>> &mat, int cur) {
for (int i = 0; i < mat.size(); i++) {
mat[i][cur] = 0;
}
}
// 得到最大的全零行数
int getMaxRows(vector<vector<int>>& mat) {
int res = 0;
for (auto row : mat) {
int flag = 0;
for(auto ele : row) {
flag |= ele;
if (flag) break;
}
if (flag == 0) res++;
}
return res;
}
int res = 0;
void dfs(vector<vector<int>> &mat, int cur, int coveredRows, int numSelect) {
// if () return;
// cout << "cur: " << cur << "coveredRows: "<< coveredRows <<"numSelect:" << numSelect << endl;
if (cur == mat[0].size() || numSelect <= 0 || mat[0].size() - cur < numSelect) {
res = max(res, coveredRows);
return;
};
vector<vector<int>> tmp = mat;
// 选了第cur 列
processMat(tmp, cur);
dfs(tmp, cur + 1, getMaxRows(tmp), numSelect - 1);
// 不选第cur 列
dfs(mat, cur + 1, coveredRows, numSelect);
}
int maximumRows(vector<vector<int>>& matrix, int numSelect) {
dfs(matrix, 0, 0, numSelect);
return res;
}
};
使用位运算优化getMaxRows 到O(n)
class Solution {
public:
// 将Mat 第cur 列设为0
void processMat(vector<int> &mat, int cur) {
int s = ~ (1 << cur);
for (int i = 0; i < mat.size(); i++) {
mat[i] &= s;
}
}
// 得到最大的全零行数
int getMaxRows(vector<int>& mat) {
int res = 0;
for (auto row : mat) {
if (row == 0) res++;
}
return res;
}
int res = 0;
void dfs(vector<int> &mat, int cur, int coveredRows, int numSelect, int n) {
// if () return;
// cout << "cur: " << cur << "coveredRows: "<< coveredRows <<"numSelect:" << numSelect << endl;
if (cur == n || numSelect <= 0 || n - cur < numSelect) {
res = max(res, coveredRows);
return;
};
// 不选第cur 列
dfs(mat, cur + 1, coveredRows, numSelect, n);
// 选了第cur 列
processMat(mat, cur);
dfs(mat, cur + 1, getMaxRows(mat), numSelect - 1, n);
}
int maximumRows(vector<vector<int>>& matrix, int numSelect) {
vector<int> mat;
for (auto row : matrix) {
int v = 0;
for (int i = 0; i < row.size(); i++) {
v |= (row[i] << i);
}
mat.push_back(v);
// cout <<"v: " << v << endl;
}
dfs(mat, 0, 0, numSelect, matrix[0].size());
return res;
}
};
进一步整理
class Solution {
public:
// 将Mat 第cur 列设为0, 并统计得到最大的全零行数
int mergeAndgetMaxRows(vector<int>& mat, int s) {
int res = 0;
for (auto row : mat) {
row = row & ~s;
if (row == 0) res++;
}
return res;
}
int res = 0;
// 引入state变量, 二进制, 对应位为1,表示选择对应列
// 引入state 好处,是可以 将mat 对应列清零函数processMat(mat, cur);和 统计最大的全零行数 合到一起
void dfs(vector<int> &mat, int cur, int state, int coveredRows, int numSelect, int n) {
if (cur == n || numSelect <= 0 || n - cur < numSelect) {
res = max(res, coveredRows);
return;
};
// 不选第cur 列
dfs(mat, cur + 1, state, coveredRows, numSelect, n);
// 选了第cur 列
state |= (1 << cur);
dfs(mat, cur + 1, state, mergeAndgetMaxRows(mat, state), numSelect - 1, n);
}
int maximumRows(vector<vector<int>>& matrix, int numSelect) {
vector<int> mat;
for (auto row : matrix) {
int v = 0;
for (int i = 0; i < row.size(); i++) {
v |= (row[i] << i);
}
mat.push_back(v);
}
dfs(mat, 0, 0, 0, numSelect, matrix[0].size());
return res;
}
};