当前位置: 首页 > news >正文

*算法训练(leetcode)第四十五天 | 101. 孤岛的总面积、102. 沉没孤岛、103. 水流问题、104. 建造最大岛屿

刷题记录

  • 101. 孤岛的总面积
    • DFS
    • BFS
  • 102. 沉没孤岛
    • DFS
    • BFS
  • *103. 水流问题
  • *104. 建造最大岛屿

101. 孤岛的总面积

题目地址

本题要求不与矩阵边缘相连的孤岛的总面积。先将与四个边缘相连的岛屿变为海洋,再统计剩余的孤岛的总面积。无需再标识访问过的结点,因为访问过后都变为海洋了。

时间复杂度: O ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( n 2 ) O(n^2) O(n2)

DFS

// c++
#include<bits/stdc++.h>
using namespace std;
int direction[4][2] = {0, 1, 0, -1, -1, 0, 1, 0};
int result = 0;void pre_dfs(vector<vector<int>> &matrix, int x, int  y){matrix[x][y] = 0;result++;for(int i=0; i<4; i++){int nextx = x + direction[i][0];int nexty = y + direction[i][1];if(nextx>=matrix.size() || nexty>=matrix[0].size() || nextx<0 || nexty<0) continue;if(matrix[nextx][nexty]){matrix[nextx][nexty] = 0;pre_dfs(matrix, nextx, nexty);}}
}int main(){int n,m;cin>>n>>m;vector<vector<int>> matrix(n, vector<int>(m, 0));for(int i=0; i<n; i++){for(int j=0; j<m; j++){cin>>matrix[i][j];}}for(int i=0; i<n; i++) {if(matrix[i][0]){pre_dfs(matrix, i, 0);}if(matrix[i][m-1]){pre_dfs(matrix, i, m-1);}}for(int j=0; j<m; j++){if(matrix[0][j]){pre_dfs(matrix, 0, j);}if(matrix[n-1][j]){pre_dfs(matrix, n-1, j);   }}result = 0;for(int i=0; i<n; i++){for(int j=0; j<m; j++){if(matrix[i][j]){pre_dfs(matrix, i, j);   }}}cout<<result;return 0;
}

BFS

// c++
#include<bits/stdc++.h>
using namespace std;
int direction[4][2] = {0, 1, 0, -1, -1, 0, 1, 0};
int result = 0;void pre_dfs(vector<vector<int>> &matrix, int x, int  y){matrix[x][y] = 0;result++;for(int i=0; i<4; i++){int nextx = x + direction[i][0];int nexty = y + direction[i][1];if(nextx>=matrix.size() || nexty>=matrix[0].size() || nextx<0 || nexty<0) continue;if(matrix[nextx][nexty]){matrix[nextx][nexty] = 0;pre_dfs(matrix, nextx, nexty);}}
}void pre_bfs(vector<vector<int>> &matrix, int x, int  y){queue<pair<int, int>> que;que.push({x, y});matrix[x][y] = 0;result++;while(!que.empty()){pair<int, int> cur = que.front();que.pop();int curx = cur.first;int cury = cur.second;for(int i=0; i<4; i++){int nextx = curx + direction[i][0];int nexty = cury + direction[i][1];if(nextx>=matrix.size() || nexty>=matrix[0].size() || nextx<0 || nexty<0) continue;if(matrix[nextx][nexty]){matrix[nextx][nexty] = 0;result++;que.push({nextx, nexty});}}}
}int main(){int n,m;cin>>n>>m;vector<vector<int>> matrix(n, vector<int>(m, 0));for(int i=0; i<n; i++){for(int j=0; j<m; j++){cin>>matrix[i][j];}}/*// dfsfor(int i=0; i<n; i++) {if(matrix[i][0]){pre_dfs(matrix, i, 0);}if(matrix[i][m-1]){pre_dfs(matrix, i, m-1);}}for(int j=0; j<m; j++){if(matrix[0][j]){pre_dfs(matrix, 0, j);}if(matrix[n-1][j]){pre_dfs(matrix, n-1, j);   }}*/// bfsfor(int i=0; i<n; i++) {if(matrix[i][0]){pre_bfs(matrix, i, 0);}if(matrix[i][m-1]){pre_bfs(matrix, i, m-1);}}for(int j=0; j<m; j++){if(matrix[0][j]){pre_bfs(matrix, 0, j);}if(matrix[n-1][j]){pre_bfs(matrix, n-1, j);   }}result = 0;for(int i=0; i<n; i++){for(int j=0; j<m; j++){if(matrix[i][j]){// pre_dfs(matrix, i, j);   pre_bfs(matrix, i, j);}}}cout<<result;return 0;
}

102. 沉没孤岛

题目地址

本题是上一题的反向操作

先把非孤岛做访问标记,再对剩余陆地进行操作。

时间复杂度: O ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( n 2 ) O(n^2) O(n2)

DFS

// c++
#include<bits/stdc++.h>
using namespace std;
int direction[][2] = {0, 1, 0, -1, -1, 0, 1, 0};
void pre_dfs(const vector<vector<int>>& matrix,vector<vector<bool>>& visited,int x, int y){visited[x][y] = true;for(int i=0; i<4; i++){int nextx = x + direction[i][0];int nexty = y + direction[i][1];if(nextx>=matrix.size() || nexty>=matrix.size() ||nextx<0 || nexty<0) continue;if(matrix[nextx][nexty] && !visited[nextx][nexty]){// visited[nextx][nexty] = true;pre_dfs(matrix, visited, nextx, nexty);}}
}void dfs(vector<vector<int>>& matrix,vector<vector<bool>>& visited,int x, int y){matrix[x][y] = 0;for(int i=0; i<4; i++){int nextx = x + direction[i][0];int nexty = y + direction[i][1];if(nextx>=matrix.size() || nexty>=matrix.size() ||nextx<0 || nexty<0) continue;if(matrix[nextx][nexty] && !visited[nextx][nexty]){visited[nextx][nexty] = true;dfs(matrix, visited, nextx, nexty);}}
}
int main(){int n,m;cin>>n>>m;vector<vector<int>> matrix(n, vector<int>(m, 0));vector<vector<bool>> visited(n, vector<bool>(m, false));for(int i=0; i<n; i++){for(int j=0; j<m; j++){cin>>matrix[i][j];}}for(int i=0; i<n; i++){if(matrix[i][0] && !visited[i][0]) pre_dfs(matrix, visited, i, 0);if(matrix[i][m-1] && !visited[i][m-1]) pre_dfs(matrix, visited, i, m-1);}for(int j=0; j<m; j++){if(matrix[0][j] && !visited[0][j]) pre_dfs(matrix, visited, 0, j);if(matrix[n-1][j] && !visited[n-1][j]) pre_dfs(matrix, visited, n-1, j);}for(int i=0; i<n; i++){for(int j=0; j<m; j++){if(matrix[i][j] && !visited[i][j]){visited[i][j] = true;dfs(matrix,visited, i, j);}}for(int j=0; j<m; j++) cout<<matrix[i][j]<<" ";cout<<endl;}return 0;
}

BFS

//c++
#include<bits/stdc++.h>
using namespace std;
int direction[][2] = {0, 1, 0, -1, -1, 0, 1, 0};
void pre_dfs(const vector<vector<int>>& matrix,vector<vector<bool>>& visited,int x, int y){visited[x][y] = true;for(int i=0; i<4; i++){int nextx = x + direction[i][0];int nexty = y + direction[i][1];if(nextx>=matrix.size() || nexty>=matrix.size() ||nextx<0 || nexty<0) continue;if(matrix[nextx][nexty] && !visited[nextx][nexty]){// visited[nextx][nexty] = true;pre_dfs(matrix, visited, nextx, nexty);}}
}void dfs(vector<vector<int>>& matrix,vector<vector<bool>>& visited,int x, int y){matrix[x][y] = 0;for(int i=0; i<4; i++){int nextx = x + direction[i][0];int nexty = y + direction[i][1];if(nextx>=matrix.size() || nexty>=matrix.size() ||nextx<0 || nexty<0) continue;if(matrix[nextx][nexty] && !visited[nextx][nexty]){visited[nextx][nexty] = true;dfs(matrix, visited, nextx, nexty);}}
}void pre_bfs(const vector<vector<int>>& matrix,vector<vector<bool>>& visited,int x, int y){visited[x][y] = true;queue<pair<int, int>> que;que.push({x,y});while(!que.empty()){pair<int, int> cur = que.front();que.pop();int curx = cur.first;int cury = cur.second;for(int i=0; i<4; i++){int nextx = curx + direction[i][0];int nexty = cury + direction[i][1];if(nextx>=matrix.size() || nexty>=matrix.size() ||nextx<0 || nexty<0) continue;if(matrix[nextx][nexty] && !visited[nextx][nexty]){visited[nextx][nexty] = true;que.push({nextx, nexty});}}}
}void bfs(vector<vector<int>>& matrix,vector<vector<bool>>& visited,int x, int y){visited[x][y] = true;matrix[x][y] = 0;queue<pair<int, int>> que;que.push({x,y});while(!que.empty()){pair<int, int> cur = que.front();que.pop();int curx = cur.first;int cury = cur.second;for(int i=0; i<4; i++){int nextx = curx + direction[i][0];int nexty = cury + direction[i][1];if(nextx>=matrix.size() || nexty>=matrix.size() ||nextx<0 || nexty<0) continue;if(matrix[nextx][nexty] && !visited[nextx][nexty]){visited[nextx][nexty] = true;matrix[nextx][nexty] = 0;que.push({nextx, nexty});}}}
}
int main(){int n,m;cin>>n>>m;vector<vector<int>> matrix(n, vector<int>(m, 0));vector<vector<bool>> visited(n, vector<bool>(m, false));for(int i=0; i<n; i++){for(int j=0; j<m; j++){cin>>matrix[i][j];}}/*// dfsfor(int i=0; i<n; i++){if(matrix[i][0] && !visited[i][0]) pre_dfs(matrix, visited, i, 0);if(matrix[i][m-1] && !visited[i][m-1]) pre_dfs(matrix, visited, i, m-1);}for(int j=0; j<m; j++){if(matrix[0][j] && !visited[0][j]) pre_dfs(matrix, visited, 0, j);if(matrix[n-1][j] && !visited[n-1][j]) pre_dfs(matrix, visited, n-1, j);}*/// bfsfor(int i=0; i<n; i++){if(matrix[i][0] && !visited[i][0]) pre_bfs(matrix, visited, i, 0);if(matrix[i][m-1] && !visited[i][m-1]) pre_bfs(matrix, visited, i, m-1);}for(int j=0; j<m; j++){if(matrix[0][j] && !visited[0][j]) pre_bfs(matrix, visited, 0, j);if(matrix[n-1][j] && !visited[n-1][j]) pre_bfs(matrix, visited, n-1, j);}for(int i=0; i<n; i++){for(int j=0; j<m; j++){if(matrix[i][j] && !visited[i][j]){// visited[i][j] = true;// dfs(matrix,visited, i, j);bfs(matrix,visited, i, j);}}for(int j=0; j<m; j++) cout<<matrix[i][j]<<" ";cout<<endl;}return 0;
}

*103. 水流问题

题目地址

使用两个标识访问的数组分别从两组边界出发进行dfs遍历,使用从低向高流(反向流)来分别记录两组边界的结点。最后两组边界的交集就是本题答案。
思路

时间复杂度: O ( m ∗ n ) O(m*n) O(mn)
空间复杂度: O ( m ∗ n ) O(m*n) O(mn)

// c++
#include<bits/stdc++.h>
using namespace std;
int direction[][2] = {0, 1, 0, -1, -1, 0, 1, 0};
void dfs(const vector<vector<int>> &matrix, vector<vector<bool>> &visited,int x, int y){visited[x][y] = true;for(int i=0; i<4; i++){int nextx = x + direction[i][0];int nexty = y + direction[i][1];if(nextx>=matrix.size() || nexty>=matrix[0].size() || nextx<0 || nexty<0) continue;if(matrix[x][y]>matrix[nextx][nexty]) continue;if(!visited[nextx][nexty]) dfs(matrix, visited, nextx, nexty);}
}int main(){int n,m;cin>>n>>m;vector<vector<int>> matrix(n, vector<int>(m, 0));vector<vector<bool>> first(n, vector<bool>(m, false));vector<vector<bool>> second(n, vector<bool>(m, false));for(int i=0; i<n; i++){for(int j=0; j<m; j++){cin>>matrix[i][j];}}for(int i=0; i<n; i++){dfs(matrix, first, i, 0);dfs(matrix, second, i, m-1);}for(int j=0; j<m; j++){dfs(matrix, first, 0, j);dfs(matrix, second, n-1, j);}for(int i=0; i<n; i++){for(int j=0; j<m; j++){if(first[i][j] && second[i][j]) cout<<i<<" "<<j<<endl;}}return 0;   
}

*104. 建造最大岛屿

题目地址

分两阶段。

  1. 先对地图中的陆地进行一次遍历,对每一个岛屿进行标记,同时计算每个岛屿的面积。
  2. 再对地图中的水域进行一次遍历,计算每一个水域变成陆地后的连续陆地面积,就是把水域四个方向的陆地面积求和,再加上1表示当前水域变为陆地。

题解

时间复杂度: O ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( n 2 ) O(n^2) O(n2)

// c++
#include<bits/stdc++.h>
using namespace std;
int direction[4][2] = {0, 1, 0, -1, -1, 0, 1, 0};void dfs(vector<vector<int>> &matrix, vector<vector<bool>> &visited, int x, int  y, int &count, int mark){visited[x][y] = true;matrix[x][y] = mark;count++;for(int i=0; i<4; i++){int nextx = x + direction[i][0];int nexty = y + direction[i][1];if(nextx>=matrix.size() || nexty>=matrix[0].size() || nextx<0 || nexty<0) continue;if(matrix[nextx][nexty] == 1 && !visited[nextx][nexty]){dfs(matrix, visited, nextx, nexty, count, mark);}}
}int main(){int n,m;cin>>n>>m;vector<vector<int>> matrix(n, vector<int>(m, 0));for(int i=0; i<n; i++){for(int j=0; j<m; j++){cin>>matrix[i][j];}}vector<vector<bool>> visited(n, vector<bool>(m, false));// 记录岛屿面积unordered_map<int, int> markCount;int mark = 2;int count;bool isAllGrid = true;// 第一阶段:记录岛屿大小for(int i=0; i<n; i++){for(int j=0; j<m; j++){if(matrix[i][j] == 0) isAllGrid = false;if(matrix[i][j] == 1 && !visited[i][j]){count = 0;dfs(matrix, visited, i, j, count, mark);markCount[mark] = count;mark++;}}}if(isAllGrid) {cout<<n*m<<endl;return 0;}int result = 0;// 第二阶段for(int i=0; i<n; i++){for(int j=0; j<m; j++){// 非陆地 计算把当前水域变为陆地的最大面积if(matrix[i][j] == 0){unordered_set<int> lands;// 把当前水域变为陆地count = 1;// 遍历当前水域的四个方向 把四个方向的陆地面积都加起来for(int k=0; k<4; k++){int nextx = i + direction[k][0];int nexty = j + direction[k][1];if(nextx>=matrix.size() || nexty>=matrix[0].size() || nextx<0 || nexty<0) continue;// 当前陆地已加入if(lands.count(matrix[nextx][nexty])>0) continue;count += markCount[matrix[nextx][nexty]];// 标记已加入的节点lands.insert(matrix[nextx][nexty]);}}result = max(result, count);}}cout<<result;return 0;
}

相关文章:

  • 密码学基础:搞懂Hash函数SHA1、SHA-2、SHA3(1)
  • Golang | Leetcode Golang题解之第328题奇偶链表
  • 汽车测试,引领国际
  • [24年新算法]NRBO-XGBoost回归+交叉验证基于牛顿拉夫逊优化算法-XGBoost多变量回归预测
  • C语言实现游戏2048(超详细!!!超易懂!!!)
  • 中职云计算实训室
  • 《密码编码学与网络安全原理与实践》第三章 传统加密技术
  • Tomcat启动控制台乱码解决方案
  • 【Pytorch实用教程】nn.Conv2d的详细介绍
  • 【漏洞复现】maxView Storage Manager 远程代码执行漏洞
  • 51单片机—智能垃圾桶(定时器)
  • Linux磁盘管理_文件系统
  • MySQL1 DDL数据定义语言
  • Linux 安装指南
  • 驰骋BPM RunSQL_Init接口SQL注入漏洞复现 [附POC]
  • $translatePartialLoader加载失败及解决方式
  • [译] 怎样写一个基础的编译器
  • iOS 系统授权开发
  • JavaScript类型识别
  • LeetCode29.两数相除 JavaScript
  • MYSQL 的 IF 函数
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • Spark RDD学习: aggregate函数
  • 闭包,sync使用细节
  • 彻底搞懂浏览器Event-loop
  • 排序(1):冒泡排序
  • 漂亮刷新控件-iOS
  • 微信小程序填坑清单
  • 用 Swift 编写面向协议的视图
  • Java总结 - String - 这篇请使劲喷我
  • #include<初见C语言之指针(5)>
  • $.ajax中的eval及dataType
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (13)DroneCAN 适配器节点(一)
  • (9)目标检测_SSD的原理
  • (二刷)代码随想录第15天|层序遍历 226.翻转二叉树 101.对称二叉树2
  • (附源码)ssm码农论坛 毕业设计 231126
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理 第13章 项目资源管理(七)
  • (三)docker:Dockerfile构建容器运行jar包
  • (十七)Flink 容错机制
  • (顺序)容器的好伴侣 --- 容器适配器
  • (一)python发送HTTP 请求的两种方式(get和post )
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • **python多态
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET Core 中的路径问题
  • .NET6使用MiniExcel根据数据源横向导出头部标题及数据
  • .NetCore+vue3上传图片 Multipart body length limit 16384 exceeded.
  • .NET正则基础之——正则委托
  • @ConditionalOnProperty注解使用说明
  • @GetMapping和@RequestMapping的区别
  • @manytomany 保存后数据被删除_[Windows] 数据恢复软件RStudio v8.14.179675 便携特别版...
  • [ vulhub漏洞复现篇 ] GhostScript 沙箱绕过(任意命令执行)漏洞CVE-2019-6116
  • [22]. 括号生成