• 【数组】最大人工岛


    题目描述

    给你一个大小为 n x n 二进制矩阵 grid 。最多 只能将一格 0 变成 1 。返回执行此操作后,grid 中最大的岛屿面积是多少?

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

    示例 1:

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

    解题思路 

    将每个区块进行编号,并且把每个编号的面积存储到MAP中;遍历grid,如果grid[i][j]==0, 则check是否有有相连的编号,并且将所有编号的面积加起来,取最大值。

    • 构造一个MAP map = new HashMap();
    • 使用dfs遍历每个位置,并且更新每个位置的值,规则int tag = start + i * grid.length + j ; 计算每个小岛的面积S,并且设置map.put(tag, S);
    • 从0到grid.length * grid.length 进行遍历,令max 设置成 map中的最大值; 
      • 如果grid[i][j]==0,则计算4个方向加起来的面积为res;
      • 计算最大的面积,max = Math.max(res,max);
    • 返回max;

    代码实现

    1. import java.util.HashSet;
    2. import java.util.Set;
    3. class Solution {
    4. int[][] direct = new int[][]{
    5. {1, 0}, {-1, 0}, {0, 1}, {0, -1}
    6. };
    7. public int largestIsland(int[][] grid) {
    8. // 默认启动位置设置成2
    9. int start = 2;
    10. int map[] = new int[start + grid.length * grid[0].length];
    11. int max = 0;
    12. for (int i = 0; i < grid.length; i++) {
    13. for (int j = 0; j < grid[i].length; j++) {
    14. if (grid[i][j] == 1) {
    15. int tag = start + i * grid.length + j;
    16. grid[i][j] = tag;
    17. int v = 1 + dfs(grid, tag, i, j);
    18. max = Math.max(max, v);
    19. map[tag] = v;
    20. }
    21. }
    22. }
    23. for (int i = 0; i < grid.length; i++) {
    24. for (int j = 0; j < grid[i].length; j++) {
    25. if (grid[i][j] == 0) {
    26. Set set = new HashSet<>();
    27. int res = 0;
    28. for (int[] d : direct) {
    29. int y = i + d[0];
    30. int x = j + d[1];
    31. if (y < grid.length && y >= 0 && x < grid[i].length && x >= 0 && grid[y][x] >= start) {
    32. if (!set.contains(grid[y][x])) {
    33. set.add(grid[y][x]);
    34. res += map[(grid[y][x])];
    35. }
    36. }
    37. }
    38. max = Math.max(max, res + 1);
    39. }
    40. }
    41. }
    42. return max;
    43. }
    44. private int dfs(int[][] grid, int tag, int i, int j) {
    45. int res = 0;
    46. for (int[] d : direct) {
    47. int y = i + d[0];
    48. int x = j + d[1];
    49. if (y < grid.length && y >= 0 && x < grid[i].length && x >= 0 && grid[y][x] == 1) {
    50. grid[y][x] = tag;
    51. res += 1;
    52. res += dfs(grid, tag, y, x);
    53. }
    54. }
    55. return res;
    56. }
    57. public static void main(String[] args) {
    58. Solution solution = new Solution();
    59. System.out.println(solution.largestIsland(new int[][]{
    60. {1, 1, 0, 1},
    61. {1, 1, 0, 1},
    62. {0, 0, 0, 1},
    63. {1, 0, 1, 0}
    64. }));
    65. }
    66. }

    执行结果如下:

     

    总结

    这道题可以拆分成:1.使用DFS求解小岛面积、2.对每个小岛进行标记、3.求连通小岛的面积和。这道题我做了多次优化但是测试结果还是要67ms,欢迎有更加高效、简洁的思路回复。

  • 相关阅读:
    Redis常见数据类型下
    JAVA:如何优雅地书写if-else(策略模式、函数式接口、卫语句)
    裸奔的前端绿皮车
    Learning Hard C# 学习笔记: 6.C#中的接口
    数据结构与算法------数组
    ZooKeeper设置ACL权限控制,删除权限
    synchronized
    2023年中国大学生留学现状及未来发展规划分析:直接就业仍是毕业后的主流选择[图]
    【实战技能】初级软件开发工程师常见问题
    NebulaGraph实战:3-信息抽取构建知识图谱
  • 原文地址:https://blog.csdn.net/weiliuhong1/article/details/126919379