*算法练习(leetcode)第四十五天 | 101. 孤岛的总面积、102. 沉没孤岛、10 ...

打印 上一主题 下一主题

主题 1005|帖子 1005|积分 3025

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
101. 孤岛的总面积

题目地址
本题要求不与矩阵边缘相连的孤岛的总面积。先将与四个边缘相连的岛屿变为海洋,再统计剩余的孤岛的总面积。无需再标识访问过的结点,因为访问过后都变为海洋了。
时间复杂度:                                    O                         (                                   n                            2                                  )                              O(n^2)                  O(n2)
空间复杂度:                                    O                         (                                   n                            2                                  )                              O(n^2)                  O(n2)
DFS

  1. // c++
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. int direction[4][2] = {0, 1, 0, -1, -1, 0, 1, 0};
  5. int result = 0;
  6. void pre_dfs(vector<vector<int>> &matrix, int x, int  y){
  7.    
  8.     matrix[x][y] = 0;
  9.     result++;
  10.     for(int i=0; i<4; i++){
  11.         int nextx = x + direction[i][0];
  12.         int nexty = y + direction[i][1];
  13.         if(nextx>=matrix.size() || nexty>=matrix[0].size() || nextx<0 || nexty<0) continue;
  14.         if(matrix[nextx][nexty]){
  15.             matrix[nextx][nexty] = 0;
  16.             
  17.             pre_dfs(matrix, nextx, nexty);
  18.         }
  19.         
  20.     }
  21. }
  22. int main(){
  23.     int n,m;
  24.     cin>>n>>m;
  25.     vector<vector<int>> matrix(n, vector<int>(m, 0));
  26.     for(int i=0; i<n; i++){
  27.         for(int j=0; j<m; j++){
  28.             cin>>matrix[i][j];
  29.         }
  30.     }
  31.    
  32.     for(int i=0; i<n; i++) {
  33.         if(matrix[i][0]){
  34.             pre_dfs(matrix, i, 0);
  35.         }
  36.         if(matrix[i][m-1]){
  37.             pre_dfs(matrix, i, m-1);
  38.         }
  39.     }
  40.     for(int j=0; j<m; j++){
  41.         if(matrix[0][j]){
  42.             pre_dfs(matrix, 0, j);
  43.         }
  44.         if(matrix[n-1][j]){
  45.             pre_dfs(matrix, n-1, j);   
  46.         }
  47.       
  48.     }
  49.     result = 0;
  50.     for(int i=0; i<n; i++){
  51.         for(int j=0; j<m; j++){
  52.             if(matrix[i][j]){
  53.                 pre_dfs(matrix, i, j);   
  54.             }
  55.         }
  56.     }
  57.     cout<<result;
  58.     return 0;
  59. }
复制代码
BFS

  1. // c++
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. int direction[4][2] = {0, 1, 0, -1, -1, 0, 1, 0};
  5. int result = 0;
  6. void pre_dfs(vector<vector<int>> &matrix, int x, int  y){
  7.    
  8.     matrix[x][y] = 0;
  9.     result++;
  10.     for(int i=0; i<4; i++){
  11.         int nextx = x + direction[i][0];
  12.         int nexty = y + direction[i][1];
  13.         if(nextx>=matrix.size() || nexty>=matrix[0].size() || nextx<0 || nexty<0) continue;
  14.         if(matrix[nextx][nexty]){
  15.             matrix[nextx][nexty] = 0;
  16.             
  17.             pre_dfs(matrix, nextx, nexty);
  18.         }
  19.         
  20.     }
  21. }
  22. void pre_bfs(vector<vector<int>> &matrix, int x, int  y){
  23.     queue<pair<int, int>> que;
  24.     que.push({x, y});
  25.     matrix[x][y] = 0;
  26.     result++;
  27.     while(!que.empty()){
  28.         pair<int, int> cur = que.front();
  29.         que.pop();
  30.         int curx = cur.first;
  31.         int cury = cur.second;
  32.         for(int i=0; i<4; i++){
  33.             int nextx = curx + direction[i][0];
  34.             int nexty = cury + direction[i][1];
  35.             if(nextx>=matrix.size() || nexty>=matrix[0].size() || nextx<0 || nexty<0) continue;
  36.             if(matrix[nextx][nexty]){
  37.                 matrix[nextx][nexty] = 0;
  38.                 result++;
  39.                 que.push({nextx, nexty});
  40.             }
  41.         }
  42.         
  43.     }
  44. }
  45. int main(){
  46.     int n,m;
  47.     cin>>n>>m;
  48.     vector<vector<int>> matrix(n, vector<int>(m, 0));
  49.     for(int i=0; i<n; i++){
  50.         for(int j=0; j<m; j++){
  51.             cin>>matrix[i][j];
  52.         }
  53.     }
  54.     /*
  55.     // dfs
  56.     for(int i=0; i<n; i++) {
  57.         if(matrix[i][0]){
  58.             pre_dfs(matrix, i, 0);
  59.         }
  60.         if(matrix[i][m-1]){
  61.             pre_dfs(matrix, i, m-1);
  62.         }
  63.     }
  64.     for(int j=0; j<m; j++){
  65.         if(matrix[0][j]){
  66.             pre_dfs(matrix, 0, j);
  67.         }
  68.         if(matrix[n-1][j]){
  69.             pre_dfs(matrix, n-1, j);   
  70.         }
  71.       
  72.     }
  73.     */
  74.     // bfs
  75.     for(int i=0; i<n; i++) {
  76.         if(matrix[i][0]){
  77.             pre_bfs(matrix, i, 0);
  78.         }
  79.         if(matrix[i][m-1]){
  80.             pre_bfs(matrix, i, m-1);
  81.         }
  82.     }
  83.     for(int j=0; j<m; j++){
  84.         if(matrix[0][j]){
  85.             pre_bfs(matrix, 0, j);
  86.         }
  87.         if(matrix[n-1][j]){
  88.             pre_bfs(matrix, n-1, j);   
  89.         }
  90.       
  91.     }
  92.     result = 0;
  93.     for(int i=0; i<n; i++){
  94.         for(int j=0; j<m; j++){
  95.             if(matrix[i][j]){
  96.                 // pre_dfs(matrix, i, j);   
  97.                 pre_bfs(matrix, i, j);
  98.             }
  99.         }
  100.     }
  101.     cout<<result;
  102.     return 0;
  103. }
复制代码
102. 沉没孤岛

题目地址
本题是上一题的反向操纵
先把非孤岛做访问标记,再对剩余陆地举行操纵。
时间复杂度:                                    O                         (                                   n                            2                                  )                              O(n^2)                  O(n2)
空间复杂度:                                    O                         (                                   n                            2                                  )                              O(n^2)                  O(n2)
DFS

  1. // c++
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. int direction[][2] = {0, 1, 0, -1, -1, 0, 1, 0};
  5. void pre_dfs(const vector<vector<int>>& matrix,
  6.             vector<vector<bool>>& visited,
  7.             int x, int y){
  8.     visited[x][y] = true;
  9.     for(int i=0; i<4; i++){
  10.         int nextx = x + direction[i][0];
  11.         int nexty = y + direction[i][1];
  12.         if(nextx>=matrix.size() || nexty>=matrix.size() ||nextx<0 || nexty<0) continue;
  13.         if(matrix[nextx][nexty] && !visited[nextx][nexty]){
  14.             // visited[nextx][nexty] = true;
  15.             pre_dfs(matrix, visited, nextx, nexty);
  16.         }
  17.     }
  18. }
  19. void dfs(vector<vector<int>>& matrix,
  20.             vector<vector<bool>>& visited,
  21.             int x, int y){
  22.     matrix[x][y] = 0;
  23.     for(int i=0; i<4; i++){
  24.         int nextx = x + direction[i][0];
  25.         int nexty = y + direction[i][1];
  26.         if(nextx>=matrix.size() || nexty>=matrix.size() ||nextx<0 || nexty<0) continue;
  27.         if(matrix[nextx][nexty] && !visited[nextx][nexty]){
  28.             visited[nextx][nexty] = true;
  29.             dfs(matrix, visited, nextx, nexty);
  30.         }
  31.     }
  32. }
  33. int main(){
  34.     int n,m;
  35.     cin>>n>>m;
  36.     vector<vector<int>> matrix(n, vector<int>(m, 0));
  37.     vector<vector<bool>> visited(n, vector<bool>(m, false));
  38.     for(int i=0; i<n; i++){
  39.         for(int j=0; j<m; j++){
  40.             cin>>matrix[i][j];
  41.         }
  42.     }
  43.     for(int i=0; i<n; i++){
  44.         if(matrix[i][0] && !visited[i][0]) pre_dfs(matrix, visited, i, 0);
  45.         if(matrix[i][m-1] && !visited[i][m-1]) pre_dfs(matrix, visited, i, m-1);
  46.     }
  47.    
  48.     for(int j=0; j<m; j++){
  49.         if(matrix[0][j] && !visited[0][j]) pre_dfs(matrix, visited, 0, j);
  50.         if(matrix[n-1][j] && !visited[n-1][j]) pre_dfs(matrix, visited, n-1, j);
  51.     }
  52.    
  53.     for(int i=0; i<n; i++){
  54.         
  55.         
  56.         for(int j=0; j<m; j++){
  57.             if(matrix[i][j] && !visited[i][j]){
  58.                 visited[i][j] = true;
  59.                 dfs(matrix,visited, i, j);
  60.             }
  61.         }
  62.         for(int j=0; j<m; j++) cout<<matrix[i][j]<<" ";
  63.         cout<<endl;
  64.         
  65.     }
  66.    
  67.    
  68.    
  69.    
  70.     return 0;
  71. }
复制代码
BFS

  1. //c++
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. int direction[][2] = {0, 1, 0, -1, -1, 0, 1, 0};
  5. void pre_dfs(const vector<vector<int>>& matrix,
  6.             vector<vector<bool>>& visited,
  7.             int x, int y){
  8.     visited[x][y] = true;
  9.     for(int i=0; i<4; i++){
  10.         int nextx = x + direction[i][0];
  11.         int nexty = y + direction[i][1];
  12.         if(nextx>=matrix.size() || nexty>=matrix.size() ||nextx<0 || nexty<0) continue;
  13.         if(matrix[nextx][nexty] && !visited[nextx][nexty]){
  14.             // visited[nextx][nexty] = true;
  15.             pre_dfs(matrix, visited, nextx, nexty);
  16.         }
  17.     }
  18. }
  19. void dfs(vector<vector<int>>& matrix,
  20.             vector<vector<bool>>& visited,
  21.             int x, int y){
  22.     matrix[x][y] = 0;
  23.    
  24.     for(int i=0; i<4; i++){
  25.         int nextx = x + direction[i][0];
  26.         int nexty = y + direction[i][1];
  27.         if(nextx>=matrix.size() || nexty>=matrix.size() ||nextx<0 || nexty<0) continue;
  28.         if(matrix[nextx][nexty] && !visited[nextx][nexty]){
  29.             visited[nextx][nexty] = true;
  30.             dfs(matrix, visited, nextx, nexty);
  31.         }
  32.     }
  33. }
  34. void pre_bfs(const vector<vector<int>>& matrix,
  35.             vector<vector<bool>>& visited,
  36.             int x, int y){
  37.     visited[x][y] = true;
  38.     queue<pair<int, int>> que;
  39.     que.push({x,y});
  40.     while(!que.empty()){
  41.         pair<int, int> cur = que.front();
  42.         que.pop();
  43.         int curx = cur.first;
  44.         int cury = cur.second;
  45.         for(int i=0; i<4; i++){
  46.             int nextx = curx + direction[i][0];
  47.             int nexty = cury + direction[i][1];
  48.             if(nextx>=matrix.size() || nexty>=matrix.size() ||nextx<0 || nexty<0) continue;
  49.             if(matrix[nextx][nexty] && !visited[nextx][nexty]){
  50.                 visited[nextx][nexty] = true;
  51.                 que.push({nextx, nexty});
  52.             }
  53.         }
  54.     }
  55. }
  56. void bfs(vector<vector<int>>& matrix,
  57.             vector<vector<bool>>& visited,
  58.             int x, int y){
  59.     visited[x][y] = true;
  60.     matrix[x][y] = 0;
  61.     queue<pair<int, int>> que;
  62.     que.push({x,y});
  63.     while(!que.empty()){
  64.         pair<int, int> cur = que.front();
  65.         que.pop();
  66.         int curx = cur.first;
  67.         int cury = cur.second;
  68.         for(int i=0; i<4; i++){
  69.             int nextx = curx + direction[i][0];
  70.             int nexty = cury + direction[i][1];
  71.             if(nextx>=matrix.size() || nexty>=matrix.size() ||nextx<0 || nexty<0) continue;
  72.             if(matrix[nextx][nexty] && !visited[nextx][nexty]){
  73.                 visited[nextx][nexty] = true;
  74.                 matrix[nextx][nexty] = 0;
  75.                 que.push({nextx, nexty});
  76.             }
  77.         }
  78.     }
  79. }
  80. int main(){
  81.     int n,m;
  82.     cin>>n>>m;
  83.     vector<vector<int>> matrix(n, vector<int>(m, 0));
  84.     vector<vector<bool>> visited(n, vector<bool>(m, false));
  85.     for(int i=0; i<n; i++){
  86.         for(int j=0; j<m; j++){
  87.             cin>>matrix[i][j];
  88.         }
  89.     }
  90.     /*
  91.     // dfs
  92.     for(int i=0; i<n; i++){
  93.         if(matrix[i][0] && !visited[i][0]) pre_dfs(matrix, visited, i, 0);
  94.         if(matrix[i][m-1] && !visited[i][m-1]) pre_dfs(matrix, visited, i, m-1);
  95.     }
  96.    
  97.     for(int j=0; j<m; j++){
  98.         if(matrix[0][j] && !visited[0][j]) pre_dfs(matrix, visited, 0, j);
  99.         if(matrix[n-1][j] && !visited[n-1][j]) pre_dfs(matrix, visited, n-1, j);
  100.     }
  101.     */
  102.     // bfs
  103.     for(int i=0; i<n; i++){
  104.         if(matrix[i][0] && !visited[i][0]) pre_bfs(matrix, visited, i, 0);
  105.         if(matrix[i][m-1] && !visited[i][m-1]) pre_bfs(matrix, visited, i, m-1);
  106.     }
  107.    
  108.     for(int j=0; j<m; j++){
  109.         if(matrix[0][j] && !visited[0][j]) pre_bfs(matrix, visited, 0, j);
  110.         if(matrix[n-1][j] && !visited[n-1][j]) pre_bfs(matrix, visited, n-1, j);
  111.     }
  112.    
  113.     for(int i=0; i<n; i++){
  114.         
  115.         
  116.         for(int j=0; j<m; j++){
  117.             if(matrix[i][j] && !visited[i][j]){
  118.                 // visited[i][j] = true;
  119.                 // dfs(matrix,visited, i, j);
  120.                 bfs(matrix,visited, i, j);
  121.             }
  122.         }
  123.         for(int j=0; j<m; j++) cout<<matrix[i][j]<<" ";
  124.         cout<<endl;
  125.         
  126.     }
  127.    
  128.    
  129.    
  130.    
  131.     return 0;
  132. }
复制代码
*103. 水流问题

题目地址
利用两个标识访问的数组分别从两组边界出发举行dfs遍历,利用从低向高流(反向流)来分别记录两组边界的结点。末了两组边界的交集就是本题答案。
思路
时间复杂度:                                    O                         (                         m                         ∗                         n                         )                              O(m*n)                  O(m∗n)
空间复杂度:                                    O                         (                         m                         ∗                         n                         )                              O(m*n)                  O(m∗n)
  1. // c++
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. int direction[][2] = {0, 1, 0, -1, -1, 0, 1, 0};
  5. void dfs(const vector<vector<int>> &matrix,
  6.         vector<vector<bool>> &visited,
  7.         int x, int y){
  8.     visited[x][y] = true;
  9.    
  10.     for(int i=0; i<4; i++){
  11.         int nextx = x + direction[i][0];
  12.         int nexty = y + direction[i][1];
  13.         if(nextx>=matrix.size() || nexty>=matrix[0].size() || nextx<0 || nexty<0) continue;
  14.         if(matrix[x][y]>matrix[nextx][nexty]) continue;
  15.         if(!visited[nextx][nexty]) dfs(matrix, visited, nextx, nexty);
  16.     }
  17. }
  18. int main(){
  19.     int n,m;
  20.     cin>>n>>m;
  21.     vector<vector<int>> matrix(n, vector<int>(m, 0));
  22.     vector<vector<bool>> first(n, vector<bool>(m, false));
  23.     vector<vector<bool>> second(n, vector<bool>(m, false));
  24.     for(int i=0; i<n; i++){
  25.         for(int j=0; j<m; j++){
  26.             cin>>matrix[i][j];
  27.         }
  28.     }
  29.    
  30.     for(int i=0; i<n; i++){
  31.         dfs(matrix, first, i, 0);
  32.         dfs(matrix, second, i, m-1);
  33.     }
  34.     for(int j=0; j<m; j++){
  35.         dfs(matrix, first, 0, j);
  36.         dfs(matrix, second, n-1, j);
  37.     }
  38.    
  39.     for(int i=0; i<n; i++){
  40.         for(int j=0; j<m; j++){
  41.             if(first[i][j] && second[i][j]) cout<<i<<" "<<j<<endl;
  42.         }
  43.     }
  44.    
  45.     return 0;   
  46. }
复制代码
*104. 制作最大岛屿

题目地址
分两阶段。

  • 先对地图中的陆地举行一次遍历,对每一个岛屿举行标记,同时盘算每个岛屿的面积。
  • 再对地图中的水域举行一次遍历,盘算每一个水域酿成陆地后的一连陆地面积,就是把水域四个方向的陆地面积求和,再加上1体现当前水域变为陆地。
题解
时间复杂度:                                    O                         (                                   n                            2                                  )                              O(n^2)                  O(n2)
空间复杂度:                                    O                         (                                   n                            2                                  )                              O(n^2)                  O(n2)
  1. // c++
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. int direction[4][2] = {0, 1, 0, -1, -1, 0, 1, 0};
  5. void dfs(vector<vector<int>> &matrix,
  6.         vector<vector<bool>> &visited,
  7.         int x, int  y, int &count, int mark){
  8.     visited[x][y] = true;
  9.     matrix[x][y] = mark;
  10.     count++;
  11.    
  12.     for(int i=0; i<4; i++){
  13.         int nextx = x + direction[i][0];
  14.         int nexty = y + direction[i][1];
  15.         if(nextx>=matrix.size() || nexty>=matrix[0].size() || nextx<0 || nexty<0) continue;
  16.         if(matrix[nextx][nexty] == 1 && !visited[nextx][nexty]){
  17.             dfs(matrix, visited, nextx, nexty, count, mark);
  18.         }
  19.     }
  20. }
  21. int main(){
  22.     int n,m;
  23.     cin>>n>>m;
  24.     vector<vector<int>> matrix(n, vector<int>(m, 0));
  25.     for(int i=0; i<n; i++){
  26.         for(int j=0; j<m; j++){
  27.             cin>>matrix[i][j];
  28.         }
  29.     }
  30.     vector<vector<bool>> visited(n, vector<bool>(m, false));
  31.     // 记录岛屿面积
  32.     unordered_map<int, int> markCount;
  33.     int mark = 2;
  34.     int count;
  35.     bool isAllGrid = true;
  36.     // 第一阶段:记录岛屿大小
  37.     for(int i=0; i<n; i++){
  38.         for(int j=0; j<m; j++){
  39.             if(matrix[i][j] == 0) isAllGrid = false;
  40.             if(matrix[i][j] == 1 && !visited[i][j]){
  41.                 count = 0;
  42.                 dfs(matrix, visited, i, j, count, mark);
  43.                 markCount[mark] = count;
  44.                 mark++;
  45.             }
  46.         }
  47.     }
  48.     if(isAllGrid) {
  49.         cout<<n*m<<endl;
  50.         return 0;
  51.     }
  52.     int result = 0;
  53.     // 第二阶段
  54.     for(int i=0; i<n; i++){
  55.         for(int j=0; j<m; j++){
  56.             // 非陆地 计算把当前水域变为陆地的最大面积
  57.             if(matrix[i][j] == 0){
  58.                 unordered_set<int> lands;
  59.                 // 把当前水域变为陆地
  60.                 count = 1;
  61.                 // 遍历当前水域的四个方向 把四个方向的陆地面积都加起来
  62.                 for(int k=0; k<4; k++){
  63.                     int nextx = i + direction[k][0];
  64.                     int nexty = j + direction[k][1];
  65.                     if(nextx>=matrix.size() || nexty>=matrix[0].size() || nextx<0 || nexty<0) continue;
  66.                     // 当前陆地已加入
  67.                     if(lands.count(matrix[nextx][nexty])>0) continue;
  68.                     
  69.                     count += markCount[matrix[nextx][nexty]];
  70.                     // 标记已加入的节点
  71.                     lands.insert(matrix[nextx][nexty]);
  72.                 }
  73.             }
  74.             
  75.             result = max(result, count);
  76.         }
  77.     }
  78.     cout<<result;
  79.     return 0;
  80. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

篮之新喜

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表