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

【优选算法】(第四十四篇)

目录

⻜地的数量(medium)

题目解析

讲解算法原理

编写代码

地图中的最⾼点(medium)

题目解析

讲解算法原理

编写代码


⻜地的数量(medium)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

给你⼀个⼤⼩为 m x n 的⼆进制矩阵 grid ,其中 0 表⽰⼀个海洋单元格、 1 表⽰⼀个陆地单元格。
⼀次移动是指从⼀个陆地单元格⾛到另⼀个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边界。
返回⽹格中⽆法在任意次数的移动中离开⽹格边界的陆地单元格的数量。

⽰例1:


输⼊:grid=[[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
输出:3
解释:有三个1被0包围。⼀个1没有被包围,因为它在边界上。
⽰例2:


输⼊:grid=[[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]]
输出:0
解释:所有1都在边界上或可以到达边界。

提⽰:
◦ m == grid.length
◦ n == grid[i].length
◦ 1 <= m, n <= 500
◦ grid[i][j] 的值为 0 或 1

讲解算法原理

解法:
算法思路:
正难则反:

从边上的 1 开始搜索,把与边上 1 相连的联通区域全部标记⼀下;然后再遍历⼀遍矩阵,看看哪些位置的 1 没有被标记即可
标记的时候,可以⽤「多源 bfs 」解决。

编写代码

c++算法代码:

class Solution
{int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};
public:int numEnclaves(vector<vector<int>>& grid) {int m = grid.size(), n = grid[0].size();vector<vector<bool>> vis(m, vector<bool>(n));queue<pair<int, int>> q;// 1. 把边上的 1 加⼊到队列中for(int i = 0; i < m; i++)for(int j = 0; j < n; j++)if(i == 0 || i == m - 1 || j == 0 || j == n - 1){if(grid[i][j] == 1){q.push({i, j});vis[i][j] = true;}}// 2. 多源 bfswhile(q.size()){auto [a, b] = q.front();q.pop();for(int i = 0; i < 4; i++){int x = a + dx[i], y = b + dy[i];if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && 
!vis[x][y]){vis[x][y] = true;q.push({x, y});}}}// 3. 统计结果int ret = 0;for(int i = 0; i < m; i++)for(int j = 0; j < n; j++)if(grid[i][j] == 1 && !vis[i][j])ret++;return ret;}
};

java算法代码:

class Solution
{int[] dx = {0, 0, 1, -1};int[] dy = {1, -1, 0, 0};public int numEnclaves(int[][] grid) {int m = grid.length, n = grid[0].length;boolean[][] vis = new boolean[m][n];Queue<int[]> q = new LinkedList<>();// 1. 把边上的 1 全部加⼊到队列中for(int i = 0; i < m; i++)for(int j = 0; j < n; j++)if(i == 0 || i == m - 1 || j == 0 || j == n - 1){if(grid[i][j] == 1){q.add(new int[]{i, j});vis[i][j] = true;}}// 2. 多源 bfswhile(!q.isEmpty()){int[] t = q.poll();int a = t[0], b = t[1];for(int i = 0; i < 4; i++){int x = a + dx[i], y = b + dy[i];if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && 
!vis[x][y]){q.add(new int[]{x, y});vis[x][y] = true;}}}// 3. 提取结果int ret = 0;for(int i = 0; i < m; i++)for(int j = 0; j < n; j++)if(grid[i][j] == 1 && !vis[i][j])ret++;return ret;}
}

地图中的最⾼点(medium)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

给你⼀个⼤⼩为 m x n 的整数矩阵 isWater ,它代表了⼀个由陆地和⽔域单元格组成的地图。
• 如果 isWater[i][j] == 0 ,格⼦ (i, j) 是⼀个陆地格⼦。
• 如果 isWater[i][j] == 1 ,格⼦ (i, j) 是⼀个⽔域格⼦。
你需要按照如下规则给每个单元格安排⾼度:
• 每个格⼦的⾼度都必须是⾮负的。
• 如果⼀个格⼦是⽔域,那么它的⾼度必须为 0 。
• 任意相邻的格⼦⾼度差⾄多为 1 。当两个格⼦在正东、南、西、北⽅向上相互紧挨着,就称它
们为相邻的格⼦。(也就是说它们有⼀条公共边)
找到⼀种安排⾼度的⽅案,使得矩阵中的最⾼⾼度值最⼤。
请你返回⼀个⼤⼩为 m x n 的整数矩阵 height ,其中 height[i][j] 是格⼦ (i, j) 的⾼度。如果有多种解法,请返回任意⼀个。

⽰例1:


输⼊:isWater=[[0,1],[0,0]]
输出:[[1,0],[2,1]]
解释:上图展⽰了给各个格⼦安排的⾼度。蓝⾊格⼦是⽔域格,绿⾊格⼦是陆地格。
⽰例2:


输⼊:isWater=[[0,0,1],[1,0,0],[0,0,0]]
输出:[[1,1,0],[0,1,1],[1,2,2]]
解释:所有安排⽅案中,最⾼可⾏⾼度为2。任意安排⽅案中,只要最⾼⾼度为2且符合上述规则的,都为可⾏⽅案。
提⽰:
◦ m == isWater.length
◦ n == isWater[i].length
◦ 1 <= m, n <= 1000
◦ isWater[i][j] 要么是 0 ,要么是 1 。◦ ⾄少有1个⽔域格⼦。

讲解算法原理

解法:
算法思路:

01矩阵的变型题,直接⽤多源bfs解决即可。

编写代码

c++算法代码:

class Solution
{int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};
public:vector<vector<int>> highestPeak(vector<vector<int>>& isWater) {int m = isWater.size(), n = isWater[0].size();vector<vector<int>> dist(m, vector<int>(n, -1));queue<pair<int, int>> q;// 1. 把所有的源点加⼊到队列⾥⾯for(int i = 0; i < m; i++)for(int j = 0; j < n; j++)if(isWater[i][j]){dist[i][j] = 0;q.push({i, j});}// 2. 多源 bfswhile(q.size()){auto [a, b] = q.front(); q.pop();for(int i = 0; i < 4; i++){int x = a + dx[i], y = b + dy[i];if(x >= 0 && x < m && y >= 0 && y < n && dist[x][y] == -1){dist[x][y] = dist[a][b] + 1;q.push({x, y});}}}return dist;}
};

java算法代码:

class Solution
{int[] dx = {0, 0, -1, 1};int[] dy = {1, -1, 0, 0};public int[][] highestPeak(int[][] isWater) {int m = isWater.length, n = isWater[0].length;int[][] dist = new int[m][n];for(int i = 0; i < m; i++)for(int j = 0; j < n; j++)dist[i][j] = -1;Queue<int[]> q = new LinkedList<>();// 1. 所有的源点加⼊到队列⾥⾯for(int i = 0; i < m; i++)for(int j = 0; j < n; j++)if(isWater[i][j] == 1){q.add(new int[]{i, j});dist[i][j] = 0;}// 2. 多源 bfswhile(!q.isEmpty()){int[] t = q.poll();int a = t[0], b = t[1];for(int i = 0; i < 4; i++){int x = a + dx[i], y = b + dy[i];if(x >= 0 && x < m && y >= 0 && y < n && dist[x][y] == -1){dist[x][y] = dist[a][b] + 1;q.add(new int[]{x, y});}}}return dist;}
}


http://www.mrgr.cn/news/51253.html

相关文章:

  • 数据结构之红黑树的实现
  • 1 -《本地部署开源大模型》如何选择合适的硬件配置
  • AI全栈大模型项目实战,人工智能,多模态大模型,微调技术训练营,大模型多场景实战
  • 算力基础篇:从零开始了解算力
  • 张驰咨询:假如国人都成为六西格玛黑带,中国将会怎样?
  • C++之《剑指offer》学习记录(4):赋值运算符函数
  • 视频分割软件哪个好?无损分割视频片段就靠它
  • 某电子元器件企业人力资源管理体系搭建咨询项目
  • 【观点】机器学习与神经网络荣膺诺贝尔物理学奖的启示:科技的未来与物理学的转变
  • 【你也能从零基础学会网站开发】SQL Server 2000中的bit数据类型
  • leetcode.3194.最小元素和最大元素的最小平均值
  • huggingface的数据集下载(linux下clone)
  • DSOL源码基本函数列表
  • 毕业32年,重回32中
  • 电流检测布局和故障排除指南
  • 【JavaEE】——TCP应答报文机制,超时重传机制
  • Find My门禁卡|苹果Find My技术与门禁卡结合,智能防丢,全球定位
  • 【Python爬虫实战】高效解析和操作XML/HTML的实用指南
  • 云开发 | 如何往云数据库中添加一条新数据
  • 开源OpenStack