827 最大人工岛

hard题目,十分困难哈,不是简单的岛屿套路,而是要经历过两次遍历,先一次遍历岛屿再一次遍历海洋

题目

给你一个大小为 n x n 二进制矩阵 grid最多 只能将一格 0 变成 1

返回执行此操作后,grid 中最大的岛屿面积是多少?

岛屿 由一组上、下、左、右四个方向相连的 1 形成。

示例 1:

lua 复制代码
输入: grid = [[1, 0], [0, 1]]
输出: 3
解释: 将一格0变成1,最终连通两个小岛得到面积为 3 的岛屿。

代码与解析

java 复制代码
class Solution {
    int n;
    Map<Integer, Integer> map = new HashMap<>();

    public int largestIsland(int[][] grid) {
        n = grid.length;
        int ans = 0;
        int index = 2;

        // 遍历整个 grid,标记陆地并计算各个岛屿的面积
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1) {
                    int t = land(grid, i, j, index); // 标记岛屿并计算面积
                    map.put(index, t); // 将岛屿编号和面积存入 map
                    index++;
                    ans = Math.max(ans, t); // 更新最大岛屿面积
                }
            }
        }

        // 处理全海洋情况
        if (ans == 0) return 1;

        // 遍历海洋区域,寻找合并后的最大岛屿面积
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 0) {
                    HashSet<Integer> set = findNeighbor(grid, i, j); // 找到相邻岛屿
                    if (set.size() < 1) continue; // 若无相邻岛屿,则跳过
                    int t = 1;
                    for (Integer m : set) t += map.get(m); // 计算合并后的岛屿面积
                    ans = Math.max(ans, t); // 更新最大岛屿面积
                }
            }
        }
        return ans;
    }

    // 查找相邻的岛屿
    public HashSet<Integer> findNeighbor(int[][] grid, int x, int y) {
        HashSet<Integer> set = new HashSet<>();
        if (!notarea(x - 1, y) && grid[x - 1][y] != 0) set.add(grid[x - 1][y]);
        if (!notarea(x + 1, y) && grid[x + 1][y] != 0) set.add(grid[x + 1][y]);
        if (!notarea(x, y - 1) && grid[x][y - 1] != 0) set.add(grid[x][y - 1]);
        if (!notarea(x, y + 1) && grid[x][y + 1] != 0) set.add(grid[x][y + 1]);
        return set;
    }

    // 标记岛屿并计算面积
    public int land(int[][] grid, int x, int y, int index) {
        if (notarea(x, y) || grid[x][y] == 0) return 0;
        if (grid[x][y] != 1) return 0;
        grid[x][y] = index;
        int region = land(grid, x, y + 1, index) + land(grid, x, y - 1, index)
                + land(grid, x + 1, y, index) + land(grid, x - 1, y, index);
        return region + 1;
    }

    // 判断是否超出边界
    public boolean notarea(int x, int y) {
        return x < 0 || y < 0 || x >= n || y >= n;
    }
}
相关推荐
名字还没想好☜6 分钟前
Go 用 bufio.Scanner 读大文件踩坑:默认 64KB 行上限、Buffer 扩容与按 Token 切分
开发语言·后端·golang·go
用户60830892904736 分钟前
SpringBoot自定义注解校验
后端
董员外37 分钟前
RAG 系统进化论(六):GraphRAG(基于知识图谱的 RAG),从相似文本走向实体关系
人工智能·后端·设计模式
Conan在掘金37 分钟前
ArkTS 进阶之道(31):状态联动深水区收官边界——为啥四级状态容器 + V1/V2 双轨是状态联动深水区收官根因
后端
Conan在掘金40 分钟前
鸿蒙 7.0 空间美学开篇:沉浸式毛玻璃 + 底部 Sheet 面板——一行 backgroundBlurStyle 玩出物理材质感
后端
Java编程爱好者42 分钟前
R2DBC vs JDBC:Spring Boot 响应式项目该怎么选
后端
AskHarries1 小时前
Sitemap 怎么自动生成
后端
神奇小汤圆1 小时前
深入 Java 线程池:从源码原理、生产调优到故障排查全链路指南
后端
Conan在掘金1 小时前
ArkTS 进阶之道(30):@Track 精准观测边界——为啥 class 属性级观测只刷关联 UI 根因
后端
明月_清风1 小时前
🚀 OpenAI 数据代理架构全解析:从 600 PB 到自然语言的六层上下文工程
前端·后端·架构