-
每日算法-最大人工岛
题目描述
给你一个大小为 n x n 二进制矩阵 grid 。最多 只能将一格 0 变成 1 。
返回执行此操作后,grid 中最大的岛屿面积是多少?
岛屿 由一组上、下、左、右四个方向相连的 1 形成。
示例1:
输入: grid = [[1, 0], [0, 1]]
输出: 3
解释: 将一格0变成1,最终连通两个小岛得到面积为 3 的岛屿。
示例2:
输入: grid = [[1, 1], [1, 0]]
输出: 4
解释: 将一格0变成1,岛屿的面积扩大为 4。
示例3:
输入: grid = [[1, 1], [1, 1]]
输出: 4
解释: 没有0可以让我们变成1,面积依然为 4。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/making-a-large-island
解答详情
这是一道DFS+二维+着色的题目,难度为hard。近日在LeetCode上刷DFS相关题的时候遇到的,觉得挺不错的一题,说一下个人的思路和见解:
如果使用暴力法:对每个海域即二维数组为0的位置进行dfs算出岛屿最大值,还需要对其置1后恢复,比较麻烦且容易出错,并且时间复杂度上在LeetCode上是肯定超时的。
其实对于DFS的题来说,一般使用DFS+回溯就能够解决了,但这毕竟是hard题,对此本人使用着色的方法,即定义一个int类型全局变量;先对二维数组进行一次DFS,将不同岛屿进行着色区分并计算出填海前(将某个0变成1)的面积;定义一个全局变量Map用于存储每个岛屿的对应面积,即颜色为key,对应面积为value;对其进行第一次DFS后,所有岛屿完成了着色并计算出填海前的面积,此时再去寻找具有相邻岛屿的海域进行填海(将某个0变成1),从而得出最大岛屿面积。
class Solution {
//全局Map,key着色,val岛屿面积
private Map<Integer,Integer> islandAreaMap = new HashMap<>();
//全局int,每个岛屿的用color值划分
private int color = -1;
public int largestIsland(int[][] grid) {
int res = 0;
int m = grid.length;
//先对二维数据进行一次dfs,得出每个岛屿的面积
for(int i = 0 ; i < m ; i++){
for(int j = 0 ; j < m ; j++){
if(grid[i][j]==1){
color --;//用于区分不同岛屿
int area = dfs(grid,i,j);//通过dfs计算岛屿面积
islandAreaMap.put(color,area);
res = Math.max(res,area);
}
}
}
//寻找相邻岛屿,填海,找最大值
for(int i = 0 ; i < m ; i++){
for(int j = 0 ; j < m ; j++){
//使用Set标记相邻岛屿面积
Set<Integer> islandAreaSet = new HashSet<>();
//判断填海位置是否具有相邻岛屿,岛屿已被着色
if(grid[i][j]==0){
if(i > 0 && grid[i-1][j]<0){
islandAreaSet.add(grid[i-1][j]);// 将岛屿颜色作为val
}
if(i < m-1 && grid[i+1][j]<0){
islandAreaSet.add(grid[i+1][j]);
}
if(j > 0 && grid[i][j-1]<0){
islandAreaSet.add(grid[i][j-1]);
}
if(j < m-1 && grid[i][j+1]<0){
islandAreaSet.add(grid[i][j+1]);
}
}
//计算填海后岛屿面积
int area = 1;
for(Integer islandColor : islandAreaSet){
area += islandAreaMap.getOrDefault(islandColor,0);
}
res = Math.max(res,area);
}
}
return res;
}
private int dfs(int[][] grid,int i,int j){
int m = grid.length;
//异常退出
if(i < 0 || j < 0 || i >= m || j >= m || grid[i][j] < 1){
return 0;
}
//对同一岛屿进行着色
if(grid[i][j]==1){
grid[i][j] = color;
}
//计算岛屿面积,对垂直/水平分别进行DFS
return 1+dfs(grid,i-1,j)+dfs(grid,i+1,j)+dfs(grid,i,j-1)+dfs(grid,i,j+1);
}
}
出处:https://www.cnblogs.com/torima/p/15228405.html
最新更新
求1000阶乘的结果末尾有多少个0
详解MyBatis延迟加载是如何实现的
IDEA 控制台中文乱码4种解决方案
SpringBoot中版本兼容性处理的实现示例
Spring的IOC解决程序耦合的实现
详解Spring多数据源如何切换
Java报错:UnsupportedOperationException in Col
使用Spring Batch实现批处理任务的详细教程
java中怎么将多个音频文件拼接合成一个
SpringBoot整合ES多个精确值查询 terms功能实
数据库审计与智能监控:从日志分析到异
SQL Server 中的数据类型隐式转换问题
SQL Server中T-SQL 数据类型转换详解
sqlserver 数据类型转换小实验
SQL Server数据类型转换方法
SQL Server 2017无法连接到服务器的问题解决
SQLServer地址搜索性能优化
Sql Server查询性能优化之不可小觑的书签查
SQL Server数据库的高性能优化经验总结
SQL SERVER性能优化综述(很好的总结,不要错
uniapp/H5 获取手机桌面壁纸 (静态壁纸)
[前端] DNS解析与优化
为什么在js中需要添加addEventListener()?
JS模块化系统
js通过Object.defineProperty() 定义和控制对象
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比