• 【数组】最大人工岛


    题目描述

    给你一个大小为 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,欢迎有更加高效、简洁的思路回复。

  • 相关阅读:
    【拼题A】 520 钻石争霸赛 2023 题解
    java版直播商城免费搭建平台规划及常见的营销模式+电商源码+小程序+三级分销+二次开发
    03.Factory Pattern 工厂模式
    被罚「带薪休假」一个月后,谷歌解雇了「爱」上 AI 的他
    java基于微信小程序+mysql+RocketMQ开发的医院智能问诊系统源码 智能导诊系统 智能导诊小程序源码
    电容笔有必要买苹果原装的吗?ipad第三方电容笔了解下
    好用的在线思维导图软件--GitMind
    注解配置SpringMVC
    音乐生毕业论文有什么好的选题?
    确保企业物联网部署安全的5个基本步骤
  • 原文地址:https://blog.csdn.net/weiliuhong1/article/details/126919379