827. Making A Large Island
You are given an n x n
binary matrix grid
. You are allowed to change at most one 0
to be 1
.
Return the size of the largest island in grid
after applying this operation.
An island is a 4-directionally connected group of 1
s.
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.
For each 1
in the grid, we paint all connected 1
with the next available color (2, 3, and so on). We also remember the size of the island we just painted with that color.
Then, we analyze all 0
in the grid, and sum sizes of connected islands (based on the island color). Note that the same island can connect to 0
more than once. The example below demonstrates this idea (the answer is highlighted):
1 class Solution { 2 public int largestIsland(int[][] grid) { 3 Map<Integer, Integer> map = new HashMap<>(); //Key: color, Val: size of island painted of that color 4 map.put(0, 0); //We won't paint island 0, hence make its size 0, we will use this value later 5 int n = grid.length; 6 int colorIndex = 2; //0 and 1 is already used in grid, hence we start colorIndex from 2 7 for (int i = 0; i < n; i++) { 8 for (int j = 0; j < n; j++) { 9 if (grid[i][j] == 1) { 10 int size = paint(grid, i, j, colorIndex); 11 map.put(colorIndex, size); 12 colorIndex++; 13 } 14 } 15 } 16 17 //If there is no island 0 from grid, res should be the size of islands of first color 18 //If there is no island 1 from grid, res should be 0 19 int res = map.getOrDefault(2, 0); 20 for (int i = 0; i < n; i++) { 21 for (int j = 0; j < n; j++) { 22 if (grid[i][j] == 0) { 23 //We use a set to avoid repeatly adding islands with the same color 24 Set<Integer> set = new HashSet<>(); 25 //If current island is at the boundary, we add 0 to the set, whose value is 0 in the map 26 set.add(i > 0 ? grid[i - 1][j] : 0); 27 set.add(i < n - 1 ? grid[i + 1][j] : 0); 28 set.add(j > 0 ? grid[i][j - 1] : 0); 29 set.add(j < n - 1 ? grid[i][j + 1] : 0); 30 31 int newSize = 1; //We need to count current island as well, hence we init newSize with 1 32 for (int color : set) newSize += map.get(color); 33 res = Math.max(res, newSize); 34 } 35 } 36 } 37 return res; 38 } 39 40 //Helper method to paint current island and all its connected neighbors 41 //Return the size of all painted islands at the end 42 private int paint(int[][] grid, int i, int j, int color) { 43 if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] != 1) return 0; 44 grid[i][j] = color; 45 return 1 + paint(grid, i + 1, j, color) + paint(grid, i - 1, j, color) + paint(grid, i, j + 1, color) + paint(grid, i, j - 1, color); 46 } 47 }
Reference: https://leetcode.com/problems/making-a-large-island/discuss/127015/C%2B%2B-with-picture-O(n*m)