[Leetcode学习-java]Making A Large Island

问题:

难度:hard

说明:

给出一个二维数组,然后数组内元素只有 0 1,1代表陆地,0代表海,那么就将所有的 1 连成一片的区域作为岛屿,你允许使用一次填充处理,将一个 0 改为 1,然后再算出海域内填充后最大的一片岛屿是多少。

题目连接:https://leetcode.com/problems/making-a-large-island/

输入范围:

  • n == grid.length
  • n == grid[i].length
  • 1 <= n <= 500
  • grid[i][j] is either 0 or 1.

输入案例:

Example 1:
Input: grid = [[1,0],[0,1]]
Output: 3
Explanation: Change one 0 to 1 and connect two 1s, then we get an island with area = 3.

Example 2:
Input: grid = [[1,1],[1,0]]
Output: 4
Explanation: Change the 0 to 1 and make the island bigger, only one island with area = 4.

Example 3:
Input: grid = [[1,1],[1,1]]
Output: 4
Explanation: Can't change any 0 to 1, only one island with area = 4.

我的代码:

首先是求岛屿面积,这个就很简单,直接一个dfs就行,如果加多一个条件,可以填充,那么我可以先算出所有的岛屿面积,然后最后逐个找到可填充的地,然后再填充看看面积如何就行了。

class Solution {

        private int max = Integer.MIN_VALUE, index = 0;
        private List<Integer> cache = new ArrayList<Integer>();

        public int largestIsland(int[][] grid) {
            if(grid.length == 0 || grid[0].length == 0) return 0;
            int x = grid.length, y = grid[0].length;
            int[][] board = new int[x][y];
            for(int i = 0; i < x; i ++) Arrays.fill(board[i], -1);
            boolean[][] visited = new boolean[x][y];
            for(int i = 0; i < x; i ++) // 先计算所有面积
                for(int j = 0; j < y; j ++)
                    if(!visited[i][j] && grid[i][j] == 1) {
                        int tmp = count(grid, i, j, visited, 0, grid.length, grid[0].length, board);
                        max = Math.max(max, tmp);
                        cache.add(tmp);
                        index ++;
                        visited[i][j] = true;
                    }

            for(int i = 0; i < x; i ++) // 再逐个填充查看面积
                for(int j = 0; j < y; j ++)
                    if(!visited[i][j]) {
                        max = Math.max(max, search(i, j, grid, board));
                        visited[i][j] = true;
                    }

            return max;
        }

        public int search(int i, int j, int[][] grid, int[][] board) {
            int val = 1, idx = -1;
            int arr[] = new int[4];
            Arrays.fill(arr, -1);

            if(isValid2(grid, i + 1, j, grid.length, grid[0].length, board, arr)) {
                val += cache.get(board[i + 1][j]);
                arr[++ idx] = board[i + 1][j];
            }
            if(isValid2(grid, i - 1, j, grid.length, grid[0].length, board, arr)) {
                val += cache.get(board[i - 1][j]);
                arr[++ idx] = board[i - 1][j];
            }
            if(isValid2(grid, i, j + 1, grid.length, grid[0].length, board, arr)) {
                val += cache.get(board[i][j + 1]);
                arr[++ idx] = board[i][j + 1];
            }
            if(isValid2(grid, i, j - 1, grid.length, grid[0].length, board, arr)) {
                val += cache.get(board[i][j - 1]);
                arr[++ idx] = board[i][j - 1];
            }

            return val;
        }

        public int count(int[][] grid, int x, int y, boolean[][] visited, int val, int xlen, int ylen, int[][] board) {
            val ++;
            board[x][y] = index;
            visited[x][y] = true;
            val = count2(grid, x + 1, y, visited, val, xlen, ylen, board);
            val = count2(grid, x - 1, y, visited, val, xlen, ylen, board);
            val = count2(grid, x, y + 1, visited, val, xlen, ylen, board);
            val = count2(grid, x, y - 1, visited, val, xlen, ylen, board);
            return val;
        }

        public int count2(int[][] grid, int x, int y, boolean[][] visited, int val, int xlen, int ylen, int[][] board) {
            if(isValid(grid, x, y, visited, xlen, ylen))
                val = count(grid, x, y, visited, val, xlen, ylen, board);
            return val;
        }

        public boolean isValid(int[][] grid, int x, int y, boolean[][] visited, int xlen, int ylen) {
            return x >= 0 && x < xlen
                    && y >= 0 && y < ylen
                    && !visited[x][y]
                    && grid[x][y] == 1;
        }

        public boolean isValid2(int[][] grid, int x, int y, int xlen, int ylen, int[][] board, int[] arr) {
            if(x >= 0 && x < xlen
            && y >= 0 && y < ylen
            && grid[x][y] == 1) {
                int tmp = board[x][y];
                for(int i = 0; i < 4; i ++)
                    if(arr[i] == tmp) return false;
                return true;
            }
            return false;
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值