#695岛屿最大面积
模板题,很快.以下两种dfs,区别是看第一个点放不放到dfs函数中处理,那么初始化的area一个是1一个是0
cpp
int dir[4][2]={0,1,0,-1,1,0,-1,0};
void dfs(int x, int y,int n, int m, int &area,vector<vector<bool>> &v, vector<vector<int>>& grid){
for(int i=0;i<4;i++){
int nextx=x+dir[i][0];
int nexty=y+dir[i][1];
if(nextx<0||nextx>=n||nexty<0||nexty>=m) continue;
if(!v[nextx][nexty] && grid[nextx][nexty]==1){
v[nextx][nexty]=true;
area++;
dfs(nextx,nexty,n,m,area,v,grid);
}
}
}
int maxAreaOfIsland(vector<vector<int>>& grid) {
int n=grid.size();
int m=grid[0].size();
vector<vector<bool>> v(n,vector<bool>(m,false));
int area;
int max=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(!v[i][j] && grid[i][j]==1){
v[i][j]=true;
area=1;
dfs(i,j,n,m,area,v,grid);
max=std::max(max,area);
}
}
}
return max;
}
cpp
int dir[4][2]={0,1,0,-1,1,0,-1,0};
void dfs(int x, int y,int n, int m, int &area,vector<vector<bool>> &v, vector<vector<int>>& grid){
v[x][y]=true;
area++;
for(int i=0;i<4;i++){
int nextx=x+dir[i][0];
int nexty=y+dir[i][1];
if(nextx<0||nextx>=n||nexty<0||nexty>=m) continue;
if(!v[nextx][nexty] && grid[nextx][nexty]==1){
v[nextx][nexty]=true;
dfs(nextx,nexty,n,m,area,v,grid);
}
}
}
int maxAreaOfIsland(vector<vector<int>>& grid) {
int n=grid.size();
int m=grid[0].size();
vector<vector<bool>> v(n,vector<bool>(m,false));
int area;
int max=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(!v[i][j] && grid[i][j]==1){
area=0;
dfs(i,j,n,m,area,v,grid);
max=std::max(max,area);
}
}
}
return max;
}
bfs:对应也有两种
cpp
int dir[4][2]={0,1,0,-1,1,0,-1,0};
void bfs(int x, int y,int n, int m, int &area,vector<vector<bool>> &v, vector<vector<int>>& grid){
queue<pair<int,int>> que;
que.push({x,y});
while(!que.empty()){
auto cur=que.front(); que.pop();
int curx=cur.first;
int cury=cur.second;
for(int i=0;i<4;i++){
int nextx=curx+dir[i][0];
int nexty=cury+dir[i][1];
if(nextx<0||nextx>=n||nexty<0||nexty>=m) continue;
if(!v[nextx][nexty] && grid[nextx][nexty]==1){
v[nextx][nexty]=true;
area++;
que.push({nextx,nexty});
}
}
}
}
int maxAreaOfIsland(vector<vector<int>>& grid) {
int n=grid.size();
int m=grid[0].size();
vector<vector<bool>> v(n,vector<bool>(m,false));
int area;
int max=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(!v[i][j] && grid[i][j]==1){
v[i][j]=true;
area=1;
bfs(i,j,n,m,area,v,grid);
max=std::max(max,area);
}
}
}
return max;
}
cpp
int dir[4][2]={0,1,0,-1,1,0,-1,0};
void bfs(int x, int y,int n, int m, int &area,vector<vector<bool>> &v, vector<vector<int>>& grid){
queue<pair<int,int>> que;
que.push({x,y});
v[x][y]=true;
area++;
while(!que.empty()){
auto cur=que.front(); que.pop();
int curx=cur.first;
int cury=cur.second;
for(int i=0;i<4;i++){
int nextx=curx+dir[i][0];
int nexty=cury+dir[i][1];
if(nextx<0||nextx>=n||nexty<0||nexty>=m) continue;
if(!v[nextx][nexty] && grid[nextx][nexty]==1){
v[nextx][nexty]=true;
area++;
que.push({nextx,nexty});
}
}
}
}
int maxAreaOfIsland(vector<vector<int>>& grid) {
int n=grid.size();
int m=grid[0].size();
vector<vector<bool>> v(n,vector<bool>(m,false));
int area;
int max=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(!v[i][j] && grid[i][j]==1){
//v[i][j]=true;
area=0;
bfs(i,j,n,m,area,v,grid);
max=std::max(max,area);
}
}
}
return max;
}
#1020飞地的数量
下面是自己写的dfs,过了但是很多可以改进。bfs也差不多这里就不写了
cpp
int dir[4][2]={0,1,0,-1,1,0,-1,0};
void dfs(int x, int y, vector<vector<int>>& grid, vector<vector<bool>> &v, int &cnt){
for(int i=0;i<4;i++){
int nextx=x+dir[i][0];
int nexty=y+dir[i][1];
if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size()) continue;
if(!v[nextx][nexty]&&grid[nextx][nexty]==1){
v[nextx][nexty]=true;
cnt++;
dfs(nextx,nexty,grid,v,cnt);
}
}
}
int numEnclaves(vector<vector<int>>& grid) {
int n=grid.size();
int m=grid[0].size();
vector<vector<bool>> v(n,vector<bool>(m,false));
int totalcnt=0;
int cnt=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(grid[i][j]==1) totalcnt++;
}
}
for(int j=0; j<m; j++){
// Do something with grid[0][j]
if(!v[0][j]&&grid[0][j]==1){
v[0][j]=true;
cnt++;
dfs(0,j,grid,v,cnt);
}
}
for(int j=0; j<m; j++){
// Do something with grid[n-1][j]
if(!v[n-1][j]&&grid[n-1][j]==1){
v[n-1][j]=true;
cnt++;
dfs(n-1,j,grid,v,cnt);
}
}
for(int i=1; i<n-1; i++){
// Do something with grid[i][0]
if(!v[i][0]&&grid[i][0]==1){
v[i][0]=true;
cnt++;
dfs(i,0,grid,v,cnt);
}
}
for(int i=1; i<n-1; i++){
// Do something with grid[i][m-1]
if(!v[i][m-1]&&grid[i][m-1]==1){
v[i][m-1]=true;
cnt++;
dfs(i,m-1,grid,v,cnt);
}
}
return totalcnt-cnt;
}
可改进的点: 1 其实遍历四周可以四个循环合为两个
2. 不需要维护一个visited, 直接把遍历过的可以走的陆地变成0海洋有点巧妙
随想录:
cpp
int dir[4][2] = {-1, 0, 0, -1, 1, 0, 0, 1};
int count; // 统计符合题目要求的陆地空格数量
void dfs(vector<vector<int>>& grid, int x, int y) {
grid[x][y] = 0;
count++;
for (int i = 0; i < 4; i++) { // 向四个方向遍历
int nextx = x + dir[i][0];
int nexty = y + dir[i][1];
if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue;
if (grid[nextx][nexty] == 0) continue;
dfs (grid, nextx, nexty);
}
return;
}
public:
int numEnclaves(vector<vector<int>>& grid) {
int n = grid.size(), m = grid[0].size();
// 从左侧边,和右侧边 向中间遍历
for (int i = 0; i < n; i++) {
if (grid[i][0] == 1) dfs(grid, i, 0);
if (grid[i][m - 1] == 1) dfs(grid, i, m - 1);
}
// 从上边和下边 向中间遍历
for (int j = 0; j < m; j++) {
if (grid[0][j] == 1) dfs(grid, 0, j);
if (grid[n - 1][j] == 1) dfs(grid, n - 1, j);
}
count = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == 1) dfs(grid, i, j);
}
}
return count;
}
#130被围绕的区域
和1020飞地是反过来的。但一开始自己想不到如何只遍历里面的。看来是做不到的,还是要靠先遍历外面。随想录思路用了第三个符号来标记(确实是三种地,内地,外地,海洋),很巧妙
想练习一下bfs,因为比dfs复杂,我总是会出小错误。bfs代码:
自己实现了25min左右吧,感觉代码确实长,东西也多,我还容易出小错误
cpp
int dir[4][2]={0,1,0,-1,1,0,-1,0};
void bfs(int x, int y, vector<vector<char>>& board, char oldc,char newc){
queue<pair<int,int>> que;
que.push({x,y});
board[x][y]=newc;
while(!que.empty()){
auto cur=que.front();que.pop();
int curx=cur.first;
int cury=cur.second;
for(int i=0;i<4;i++){
int nextx=curx+dir[i][0];
int nexty=cury+dir[i][1];
if(nextx<0||nextx>=board.size()||nexty<0||nexty>=board[0].size()) continue;
if(board[nextx][nexty]==oldc){
que.push({nextx,nexty});
board[nextx][nexty]=newc;
}
}
}
}
void solve(vector<vector<char>>& board) {
int n=board.size();
int m=board[0].size();
//itr around land,set A
for(int j=0;j<m;j++){
if(board[0][j]=='O') bfs(0,j,board,'O','A');
if(board[n-1][j]=='O') bfs(n-1,j,board,'O','A');
}
for(int i=1;i<n-1;i++){
if(board[i][0]=='O') bfs(i,0,board,'O','A');
if(board[i][m-1]=='O') bfs(i,m-1,board,'O','A');
}
//go through all, o to x
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(board[i][j]=='O') bfs(i,j,board,'O','X');
}
}
//go through all, A to o
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(board[i][j]=='A') bfs(i,j,board,'A','O');
}
}
}
出错1:忘记检查边界&continue了。记住出现runtime error很有可能就是忘记检查边界了
出错2:多个循环,相互复制,要记得改里面的i,j, char之类的!不要复制了忘记改了呜呜
#417太平洋大西洋水流问题
有思路,写出来有问题,看了随想录调整的,就过了。弄了四十多分钟
这回基本上都是逻辑思路问题,没有模板问题:
1.我想到了是从边缘逆着流上来。我原来没想到本题是两个visited,都是true就没错。
错的:我额外弄了一个叫top的2d,每次++。但有可能都从pac溜上来的两条路都可以++:
2.我原来很疑惑怎么找到一条路的末尾,其实在这道题不用找。直接两个表都是true的点就是
- 我没想明白为什么在主函数里,不用判断这些://if(!pac[0][j]),加了也没错但反而慢
cpp
int dir[4][2]={0,1,0,-1,1,0,-1,0};
void dfs(int x, int y,vector<vector<bool>> &v,vector<vector<int>>& vec){
v[x][y]=true;
for(int i=0;i<4;i++){
int nextx=x+dir[i][0];
int nexty=y+dir[i][1];
if(nextx<0||nextx>=vec.size()||nexty<0||nexty>=vec[0].size()) continue;
if(!v[nextx][nexty] && vec[nextx][nexty]>=vec[x][y]){
v[nextx][nexty]=true;
dfs(nextx,nexty,v,vec);
}
}
}
vector<vector<int>> pacificAtlantic(vector<vector<int>>& vec) {
int n=vec.size();
int m=vec[0].size();
vector<vector<bool>> pac(n, vector<bool>(m, false));
vector<vector<bool>> atl(n, vector<bool>(m, false));
vector<vector<int>> res;
//left, top
for(int j=0;j<m;j++){
//if(!pac[0][j]) dfs(0,j,pac,vec);
dfs(0,j,pac,vec);
}
for(int i=0;i<n;i++){
//if(!pac[i][0]) dfs(i,0,pac,vec);
dfs(i,0,pac,vec);
}
//right bottom
for(int j=0;j<m;j++){
//if(!atl[n-1][j]) dfs(n-1,j,atl,vec);
dfs(n-1,j,atl,vec);
}
for(int i=0;i<n;i++){
//if(!atl[i][m-1]) dfs(i,m-1,atl,vec);
dfs(i,m-1,atl,vec);
}
//check res
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(pac[i][j]&&atl[i][j]){
res.push_back({i,j});
}
}
}
return res;
}