classSolution {
public:
int m, n;
int count; // 记录连通块的个数intnumIslands(vector<vector<char>>& grid){
// 将遇到的一块陆地的连通块都变为海水,连通块加一,下次再遇到陆地依次类推
m = grid.size(), n = grid[0].size();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
dfs(grid, i, j);
count++;
}
}
}
return count;
}
int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0};
voiddfs(vector<vector<char>>& grid, int i, int j){
for (int k = 0; k < 4; k++) {
int x = dx[k] + i, y = dy[k] + j;
if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1') {
grid[x][y] = '0';
dfs(grid, x, y);
}
}
}
};
classSolution {
public:
int m, n;
int ret; // 记录最大岛屿面积int count;
bool vis[51][51];
intmaxAreaOfIsland(vector<vector<int>>& grid){
m = grid.size(), n = grid[0].size();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (!vis[i][j] && grid[i][j] == 1) {
vis[i][j] = true;
count = 0;
dfs(grid, i, j);
ret = max(ret, count);
}
}
}
return ret;
}
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
voiddfs(vector<vector<int>>& grid, int i, int j){
vis[i][j] = true;
count++;
for (int k = 0; k < 4; k++) {
int x = dx[k] + i, y = dy[k] + j;
if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y] == 1) {
// path 在参数中回溯会自动恢复现场,path 会比实际的值小dfs(grid, x, y);
}
}
}
};
怎么检查四周是被 X 围绕的呢?
正难则反,正着的情况下,如果想要修改中间的 O,需要一个 DFS,如果想要四周的 O 不变,又需要一个 DFS,如果想要将四周的 O 修改为 X,又需要回溯去还原
算法思路:
可以先使用 DFS 把四周的 O 修改为点,再在函数中将点的修改为 O,O 的修改为 X,这就是正难则反
代码
classSolution {
public:
int m, n;
voidsolve(vector<vector<char>>& board){
m = board.size(), n = board[0].size();
// 1. 把与边界'O'相连的连通块,修改为'.'for (int j = 0; j < n; j++) {
if (board[0][j] == 'O') dfs(board, 0, j);
if (board[m - 1][j] == 'O') dfs(board, m - 1, j);
}
for (int i = 0; i < m; i++) {
if (board[i][0] == 'O') dfs(board, i, 0);
if (board[i][n - 1] == 'O') dfs(board, i, n - 1);
}
// 2. 把所有的'.'还原为'O',把'O'改为'X'for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == '.') board[i][j] = 'O';
// 这里不可以写成 if,因为可能是上面的'.'修改成的'O'elseif (board[i][j] == 'O') board[i][j] = 'X';
}
}
}
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
voiddfs(vector<vector<char>>& board, int i, int j){
board[i][j] = '.';
for (int k = 0; k < 4; k++) {
int x = dx[k] + i, y = dy[k] + j;
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O') {
dfs(board, x, y);
}
}
}
};
classSolution {
public:
int m, n;
vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {
vector<vector<int>> ret;
m = heights.size(), n = heights[0].size();
vector<vector<bool>> pac(m, vector<bool>(n));
vector<vector<bool>> atl(m, vector<bool>(n));
for (int j = 0; j < n; j++) {
dfs(heights, 0, j, pac);
dfs(heights, m - 1, j, atl);
}
for (int i = 0; i < m; i++) {
dfs(heights, i, 0, pac);
dfs(heights, i, n - 1, atl);
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (pac[i][j] && atl[i][j]) ret.push_back({i, j});
}
}
return ret;
}
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
// oce 一定要传引用为了修改原始数组中的值voiddfs(vector<vector<int>>& heights, int i, int j, vector<vector<bool>>& oce){
oce[i][j] = true;
for (int k = 0; k < 4; k++) {
int x = dx[k] + i, y = dy[k] + j;
if (x >= 0 && x < m && y >= 0 && y < n && heights[i][j] <= heights[x][y] && !oce[x][y]) {
dfs(heights, x, y, oce);
}
}
}
};
classSolution {
public:
int m, n;
int count;
bool vis[101][101];
intwardrobeFinishing(int _m, int _n, int cnt){
m = _m, n = _n;
dfs(0, 0, cnt);
if (0 <= cnt) count++;
return count;
}
int dx[2] = {1, 0};
int dy[2] = {0, 1};
voiddfs(int i, int j, int cnt){
for (int k = 0; k < 2; k++) {
int x = dx[k] + i, y = dy[k] + j;
int val1 = x, sum1 = 0;
int val2 = y, sum2 = 0;
while (val1) {
sum1 += (val1 % 10);
val1 /= 10;
}
while (val2) {
sum2 += (val2 % 10);
val2 /= 10;
}
if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && sum1 + sum2 <= cnt) {
count++;
vis[x][y] = true;
dfs(x, y, cnt);
}
}
}
};