1. 程式人生 > >生成更大的陸地 Making A Large Island

生成更大的陸地 Making A Large Island

lar 連通塊 con urn 時間復雜度 private class != div

2018-10-06 19:44:18

問題描述:

技術分享圖片

問題求解:

經典的求連通塊問題的擴展,問題規模不大,可以暴力求解。

解法一、Brute Force O(n^4)

    int[][] dirs = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    public int largestIsland(int[][] grid) {
        int res = Integer.MIN_VALUE;
        int n =  grid.length;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1) res = Math.max(res, helper(grid, i, j, new int[n][n]));
                else {
                    grid[i][j] = 1;
                    res = Math.max(res, helper(grid, i, j, new int[n][n]));
                    grid[i][j] = 0;
                }
            }
        }
        return res;
    }

    private int helper(int[][] grid, int x, int y, int[][] used) {
        int n = grid.length;
        int res = 1;
        used[x][y] = 1;
        for (int[] dir : dirs) {
            int px = x + dir[0];
            int py = y + dir[1];
            if (px < 0 || px >= n || py < 0 || py >= n || used[px][py] == 1 || grid[px][py] == 0) continue;
            res += helper(grid, px, py, used);
        }
        return res;
    }

解法二、

為每個連通塊做上標記,並得到每個連通塊的面積,之後再對0進行遍歷,依次尋找其四個相鄰的邊的area,將他們加起來再從中取max。算法總的時間復雜度為O(n ^ 2)。

    public int largestIsland(int[][] grid) {
        int res = Integer.MIN_VALUE;
        int n =  grid.length;
        Map<Integer, Integer> map = new HashMap<>();
        int color = 0;
        int area = 0;
        map.put(color++, area);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1) area = dfs(grid, i, j, ++color);
                map.put(color, area);
                res = Math.max(res, area);
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 0) {
                    int curArea = 1;
                    Set<Integer> set = new HashSet<>();
                    set.add(getColor(grid, i - 1, j));
                    set.add(getColor(grid, i + 1, j));
                    set.add(getColor(grid, i, j + 1));
                    set.add(getColor(grid, i, j - 1));
                    for (int c : set) {
                        curArea += map.get(c);
                    }
                    res = Math.max(res, curArea);
                }
            }
        }
        return res;
    }

    private int getColor(int[][] grid, int x, int y) {
        if (x < 0 || x >= grid.length || y < 0 || y >= grid.length) return 0;
        else return grid[x][y];
    }

    private int dfs(int[][] grid, int x, int y, int color) {
        if (x < 0 || x >= grid.length || y < 0 || y >= grid.length || grid[x][y] != 1) return 0;
        grid[x][y] = color;
        return 1 + dfs(grid, x + 1, y, color) + dfs(grid, x - 1, y, color) +
                dfs(grid, x, y - 1, color) + dfs(grid, x, y + 1, color);
    }

生成更大的陸地 Making A Large Island