当前位置:网站首页>最大人工岛[如何让一个连通分量的所有节点都记录总节点数?+给连通分量编号]
最大人工岛[如何让一个连通分量的所有节点都记录总节点数?+给连通分量编号]
2022-07-05 17:49:00 【REN_林森】
dfs与连通分量
前言
如何求连通分量总的所有节点数?dfs+visited
如何给连通分量的所有节点都能记录该连通分量的节点总数?将变量改为数组(大家用一个堆地址)
如何确定一个节点周围的节点是否为两个不同的连通分量?给连通分量编号 or 并查集findFather
一、最大人工岛

二、DFS+记搜变体
package everyday.hard;
import java.util.HashSet;
import java.util.Set;
// 最大人工岛。
public class LargestIsland {
/* target:只能将一个格子从0变为1,看最大岛屿面积。 直观:DFS求岛屿面积, 如何举一反三?既然只能让一个0变为1,那就从0的地方dfs,但是时间复杂度非常高!O(N * N * N * N) 那用空间换时间,把每个块的提前通过dfs算好,即从1的地方dfs,每个位置都记录这个连通块的总数量。 但是,这会失败,因为0的左右连通块可能不是独立的连通块,可能就是同一个连通块,则会导致重复计算。 所以,需要给连通分量块编号,不同的连通分量块才能加在一起。 */
public int largestIsland(int[][] grid) {
int m = grid.length, n = grid[0].length;
int max = 1 << 31;
int[][][] f = new int[m][n][2];
// 从1出发dfs
int idx = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
int[] total = new int[]{
0, idx};
dfs(grid, i, j, f, total);
max = Math.max(max, total[0]);
++idx;
}
}
}
// 从0出发dfs。
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 0) {
int total = 1;
// 去重复的连通分量
Set<Integer> bool = new HashSet<>();
for (int[] gap : gaps) {
int ni = i + gap[0], nj = j + gap[1];
if (ni == -1 || -1 == nj || nj == grid[0].length || grid.length == ni || grid[ni][nj] == 0)
continue;
if (!bool.contains(f[i][j][1])) {
total += f[i][j][0];
bool.add(f[i][j][1]);
}
}
max = Math.max(max, total);
}
}
}
return max;
}
// 方便走四个方向,采用矩阵+循环的方式。
static final int[][] gaps = new int[][]{
{
1, 0}, {
-1, 0}, {
0, 1}, {
0, -1}};
// 如何让一个连通分量的所有节点处都能赋值到总节点数。
private void dfs(int[][] grid, int i, int j, int[][][] f, int[] total) {
if (i == -1 || -1 == j || j == grid[0].length || grid.length == i || grid[i][j] <= 0) return;
total[0]++;
f[i][j] = total;
grid[i][j] = -1;
for (int[] gap : gaps) {
int ni = i + gap[0], nj = j + gap[1];
dfs(grid, ni, nj, f, total);
}
}
}
总结
1)这个题是DFS+记忆搜索的改进版本,想做的举一反三,就必须牢牢掌握其细节,如访问过的需要一直标记着,不能不标记,也不能回溯把标记去掉,这不是求最大路径值;如判定下标越界,不是i == 0 || i == n,是i == -1 || i == n,这都能搞错,服了。
2)掌握了这些基础知识,根据题目需求,来做相应的利用。比如本题可把一个0变成1,那不如就从0的地方开始遍历,取最大值。
3)今天做到这个比较丧,一直感觉思路是对的(不过思路是对的,只是有坑没发现。),花了很多时间才发现关键问题所在。(发现关键问题的能力太弱了,我觉得这是核心能力!)。但是不要气馁,看了题解,才发现这是官方故意给的坑,需要打破舒适区知识,学会举一反三,循序渐进的成长。所以想丧就要笑,大声把思路读出来,想不通就去学题解,这是突破自己的好时机。
参考文献
[1] LeetCode 最大人工岛
边栏推荐
- rsync
- Abnormal recovery of virtual machine Oracle -- Xi Fenfei
- flask接口响应中的中文乱码(unicode)处理
- Size_t 是无符号的
- Operation before or after Teamcenter message registration
- [TestLink] testlink1.9.18 solutions to common problems
- 热通孔的有效放置如何改善PCB设计中的热管理?
- 怎么选择外盘期货平台最正规安全?
- ISPRS2022/云检测:Cloud detection with boundary nets基于边界网的云检测
- EPM related
猜你喜欢

Short the command line via jar manifest or via a classpath file and rerun

MATLAB查阅

Leetcode daily question: merge two ordered arrays

Oracle recovery tools -- Oracle database recovery tool

Sophon CE社区版上线,免费Get轻量易用、高效智能的数据分析工具

Sophon Base 3.1 推出MLOps功能,为企业AI能力运营插上翅膀

What are the requirements for PMP certification? How much is it?

Vulnerability recurrence - 48. Command injection in airflow DAG (cve-2020-11978)

GFS distributed file system

企业数字化发展中的六个安全陋习,每一个都很危险!
随机推荐
QT控制台打印输出
Six bad safety habits in the development of enterprise digitalization, each of which is very dangerous!
Cmake tutorial Step2 (add Library)
修复漏洞 - mysql 、es
论文阅读_中文NLP_LTP
Mask wearing detection based on yolov3
Cmake tutorial Step3 (requirements for adding libraries)
论文阅读_医疗NLP模型_ EMBERT
GFS分布式文件系统
Redis Foundation
EPM related
使用QT设计师界面类创建2个界面,通过按键从界面1切换到界面2
Sophon KG升级3.1:打破数据间壁垒,解放企业生产力
flask接口响应中的中文乱码(unicode)处理
ISPRS2022/雲檢測:Cloud detection with boundary nets基於邊界網的雲檢測
Accuracy of BigDecimal Division
求解为啥all(())是True, 而any(())是FALSE?
集群部署如何解决海量视频接入与大并发需求?
IDC report: Tencent cloud database ranks top 2 in the relational database market!
Knowledge points of MySQL (7)