#695岛屿最大面积
模板题,很快.以下两种dfs,区别是看第一个点放不放到dfs函数中处理,那么初始化的area一个是1一个是0
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;}
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:对应也有两种
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;}
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也差不多这里就不写了
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海洋 有点巧妙
随想录:
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左右吧,感觉代码确实长,东西也多,我还容易出小错误
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 Afor(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 xfor(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 ofor(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的点就是
3. 我没想明白为什么在主函数里,不用判断这些://if(!pac[0][j]),加了也没错但反而慢
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, topfor(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 bottomfor(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 resfor(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;}