1. 零矩阵
编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。
Example 1
输入:
[ [1,1,1],
[1,0,1],
[1,1,1] ]
输出:
[ [1,0,1],
[0,0,0],
[1,0,1] ]
Example 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] ]
代码
void setZeroes(vector<vector<int>> &matrix) {
list<tuple<int, int>> pos;
for (int i = 0; i < matrix.size(); ++i) {
for (int j = 0; j < matrix[0].size(); ++j) {
if (matrix[i][j] == 0) pos.push_back({i, j});
}
}
for_each(pos.begin(), pos.end(), [&](const tuple<int, int> &tp) {
for (int i = 0; i < matrix.size(); ++i) matrix[i][get<1>(tp)] = 0;
for (int j = 0; j < matrix[0].size(); ++j) matrix[get<0>(tp)][j] = 0;
});
}
2. 矩阵置零
Given an m x n
integer matrix matrix
, if an element is 0
, set its entire row and column to 0
’s.
You must do it in place.
Example 1
Input: matrix = [[1,1,1],[1,0,1],[1,1,1]]
Output: [[1,0,1],[0,0,0],[1,0,1]]
Example 2
Input: matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
Output: [[0,0,0,0],[0,4,5,0],[0,3,1,0]]
Constraints:
m == matrix.length
n == matrix[0].length
1 <= m, n <= 200
-2^31 <= matrix[i][j] <= 2^31 - 1
Follow up:
- A straightforward 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?
代码
void setZeroes(vector<vector<int>> &matrix) {
bool rowResetFlag = any_of(matrix.begin(), matrix.end(), [](const vector<int> &line) {
return line[0] == 0;
});
bool colResetFlag = any_of(matrix[0].begin(), matrix[0].end(), [](int val) {
return val == 0;
});
for (int i = 1; i < matrix.size(); ++i) {
for (int j = 1; j < matrix[0].size(); ++j) {
if (matrix[i][j] == 0) matrix[i][0] = matrix[0][j] = 0;
}
}
auto resetRow = [&](int x) { for (int j = 0; j < matrix[0].size(); ++j) matrix[x][j] = 0; };
auto resetCol = [&](int y) { for (int i = 0; i < matrix.size(); ++i) matrix[i][y] = 0; };
for (int i = 1; i < matrix.size(); ++i) {
if (matrix[i][0] == 0) resetRow(i);
}
for (int j = 0; j < matrix[0].size(); ++j) {
if (matrix[0][j] == 0) resetCol(j);
}
if (rowResetFlag) resetCol(0);
if (colResetFlag) resetRow(0);
}
3. 重新排列后的最大子矩阵
You are given a binary matrix matrix
of size m x n
, and you are allowed to rearrange the columns of the matrix
in any order.
Return the area of the largest submatrix within matrix
where every element of the submatrix is 1
after reordering the columns optimally.
Example 1
[外链图片转存中…(img-r7jZ1nWr-1654908026707)]
Input: matrix = [[0,0,1],[1,1,1],[1,0,1]]
Output: 4
Explanation: You can rearrange the columns as shown above.
The largest submatrix of 1s, in bold, has an area of 4.
Example 2
Input: matrix = [[1,0,1,0,1]]
Output: 3
Explanation: You can rearrange the columns as shown above.
The largest submatrix of 1s, in bold, has an area of 3.
Constraints:
m == matrix.length
n == matrix[i].length
1 <= m * n <= 10^5
matrix[i][j]
is either0
or1
.
代码
int largestSubmatrix(vector<vector<int>> matrix) {
for (int i = 0; i < matrix.size(); ++i)
for (int j = 0; j < matrix[0].size(); ++j)
if (matrix[i][j] != 0 & i > 0) matrix[i][j] += matrix[i - 1][j];
int result = 0;
for (auto &line:matrix) {
sort(line.begin(), line.end(), greater<>());
for (int j = 0; j < line.size(); ++j) result = max(result, line[j] * (j + 1));
}
return result;
}
4. 边界着色
You are given an m x n
integer matrix grid
, and three integers row
, col
, and color
. Each value in the grid represents the color of the grid square at that location.
Two squares belong to the same connected component if they have the same color and are next to each other in any of the 4 directions.
The border of a connected component is all the squares in the connected component that are either 4-directionally adjacent to a square not in the component, or on the boundary of the grid (the first or last row or column).
You should color the border of the connected component that contains the square grid[row][col]
with color
.
Return the final grid.
Example 1
Input: grid = [[1,1],[1,2]], row = 0, col = 0, color = 3
Output: [[3,3],[3,2]]
Example 2
Input: grid = [[1,2,2],[2,3,2]], row = 0, col = 1, color = 3
Output: [[1,3,3],[2,3,3]]
Constraints:
m == grid.length
n == grid[i].length
1 <= m, n <= 50
1 <= grid[i][j], color <= 1000
0 <= row < m
0 <= col < n
代码
class Solution {
private:
vector<pair<int, int>> DIR{{1, 0},{-1, 0},{0, 1},{0, -1}};
void dfs(vector<vector<int>> &grid, int x, int y, vector<vector<bool>> &visited, vector<pair<int, int>> &borders, int originalColor) {
int m = grid.size(), n = grid[0].size();
bool isBorder = false;
for (auto&[dx, dy]:DIR) {
int nx = x + dx, ny = y + dy;
if (nx < 0 || nx >= m || ny < 0 || ny >= n || grid[nx][ny] != originalColor) {
isBorder = true;
} else if (!visited[nx][ny]) {
visited[nx][ny] = true;
dfs(grid, nx, ny, visited, borders, originalColor);
}
}
if (isBorder) borders.emplace_back(x, y);
}
public:
vector<vector<int>> colorBorder(vector<vector<int>> grid, int row, int col, int color) {
int m = grid.size(), n = grid[0].size();
vector<vector<bool>> visited(m, vector<bool>(n, false));
vector<pair<int, int>> borders;
visited[row][col] = true;
dfs(grid, row, col, visited, borders, grid[row][col]);
for (auto &[x, y] : borders) grid[x][y] = color;
return grid;
}
};
5. 将字符串翻转到单调递增
A binary string is monotone increasing if it consists of some number of 0
’s (possibly none), followed by some number of 1
’s (also possibly none).
You are given a binary string s
. You can flip s[i]
changing it from 0
to 1
or from 1
to 0
.
Return the minimum number of flips to make s
monotone increasing.
Example 1
Input: s = "00110"
Output: 1
Explanation: We flip the last digit to get 00111.
Example 2
Input: s = "010110"
Output: 2
Explanation: We flip to get 011111, or alternatively 000111.
Constraints:
1 <= s.length <= 105
s[i]
is either'0'
or'1'
.
代码
int minFlipsMonoIncr(string s) {
vector<int> left(s.size()); // left[i] s[0,i] 包含1的个数
vector<int> right(s.size()); // right[i] s[i,n] 包含0的个数
for (int i = 0, cnt = 0; i < s.size(); ++i) left[i] = cnt = cnt + (s[i] == '1');
for (int i = s.size() - 1, cnt = 0; i >= 0; --i) right[i] = cnt = cnt + (s[i] == '0');
int result = INT_MAX;
for (int i = 0; i < s.size(); ++i) {
result = min(result, (i > 0 ? left[i - 1] : 0) + (i + 1 < s.size() ? right[i + 1] : 0));
}
return result;
}