Array
Breadth-First Search
Depth-First Search
Matrix
Union Find
Description
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.
Constraints:
n == grid.length
n == grid[i].length
1 <= n <= 500
grid[i][j]
is either 0
or 1
.
Solutions
Solution 1: DFS
We can assign a unique identifier to each connected component, using an array \(p\) to record the connected component each position belongs to, i.e., \(p[i][j]\) represents the connected component number of \((i, j)\) . Use an array \(cnt\) to record the size of each connected component, i.e., \(cnt[root]\) represents the size of the connected component \(root\) .
First, we traverse the entire matrix. For each position \(grid[i][j] = 1\) and \(p[i][j] = 0\) , we perform a depth-first search on it, mark its connected component as \(root\) , and count the size of the connected component.
Then, we traverse the entire matrix again. For each position \(grid[i][j] = 0\) , we find the connected components of the four positions above, below, left, and right of it, add up the sizes of these connected components, and add \(1\) for the current position, to get the maximum island area after changing the current position to \(1\) .
The time complexity is \(O(n^2)\) , and the space complexity is \(O(n^2)\) . Where \(n\) is the length of the sides of the matrix.
Python3 Java C++ Go TypeScript Rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 class Solution :
def largestIsland ( self , grid : List [ List [ int ]]) -> int :
def dfs ( i : int , j : int ):
p [ i ][ j ] = root
cnt [ root ] += 1
for a , b in pairwise ( dirs ):
x , y = i + a , j + b
if 0 <= x < n and 0 <= y < n and grid [ x ][ y ] and p [ x ][ y ] == 0 :
dfs ( x , y )
n = len ( grid )
cnt = Counter ()
p = [[ 0 ] * n for _ in range ( n )]
dirs = ( - 1 , 0 , 1 , 0 , - 1 )
root = 0
for i , row in enumerate ( grid ):
for j , x in enumerate ( row ):
if x and p [ i ][ j ] == 0 :
root += 1
dfs ( i , j )
ans = max ( cnt . values () or [ 0 ])
for i , row in enumerate ( grid ):
for j , x in enumerate ( row ):
if x == 0 :
s = set ()
for a , b in pairwise ( dirs ):
x , y = i + a , j + b
if 0 <= x < n and 0 <= y < n :
s . add ( p [ x ][ y ])
ans = max ( ans , sum ( cnt [ root ] for root in s ) + 1 )
return ans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 class Solution {
private int n ;
private int root ;
private int [] cnt ;
private int [][] p ;
private int [][] grid ;
private final int [] dirs = { - 1 , 0 , 1 , 0 , - 1 };
public int largestIsland ( int [][] grid ) {
n = grid . length ;
p = new int [ n ][ n ] ;
this . grid = grid ;
cnt = new int [ n * n + 1 ] ;
int ans = 0 ;
for ( int i = 0 ; i < n ; ++ i ) {
for ( int j = 0 ; j < n ; ++ j ) {
if ( grid [ i ][ j ] == 1 && p [ i ][ j ] == 0 ) {
++ root ;
ans = Math . max ( ans , dfs ( i , j ));
}
}
}
for ( int i = 0 ; i < n ; ++ i ) {
for ( int j = 0 ; j < n ; ++ j ) {
if ( grid [ i ][ j ] == 0 ) {
Set < Integer > s = new HashSet <> ();
for ( int k = 0 ; k < 4 ; ++ k ) {
int x = i + dirs [ k ] ;
int y = j + dirs [ k + 1 ] ;
if ( x >= 0 && x < n && y >= 0 && y < n ) {
s . add ( p [ x ][ y ] );
}
}
int t = 1 ;
for ( int x : s ) {
t += cnt [ x ] ;
}
ans = Math . max ( ans , t );
}
}
}
return ans ;
}
private int dfs ( int i , int j ) {
p [ i ][ j ] = root ;
++ cnt [ root ] ;
for ( int k = 0 ; k < 4 ; ++ k ) {
int x = i + dirs [ k ] ;
int y = j + dirs [ k + 1 ] ;
if ( x >= 0 && x < n && y >= 0 && y < n && grid [ x ][ y ] == 1 && p [ x ][ y ] == 0 ) {
dfs ( x , y );
}
}
return cnt [ root ] ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 class Solution {
public :
int largestIsland ( vector < vector < int >>& grid ) {
int n = grid . size ();
int p [ n ][ n ];
memset ( p , 0 , sizeof ( p ));
int cnt [ n * n + 1 ];
memset ( cnt , 0 , sizeof ( cnt ));
const int dirs [ 5 ] = { -1 , 0 , 1 , 0 , -1 };
int root = 0 ;
int ans = 0 ;
function < int ( int , int ) > dfs = [ & ]( int i , int j ) {
p [ i ][ j ] = root ;
++ cnt [ root ];
for ( int k = 0 ; k < 4 ; ++ k ) {
int x = i + dirs [ k ];
int y = j + dirs [ k + 1 ];
if ( x >= 0 && x < n && y >= 0 && y < n && grid [ x ][ y ] && ! p [ x ][ y ]) {
dfs ( x , y );
}
}
return cnt [ root ];
};
for ( int i = 0 ; i < n ; ++ i ) {
for ( int j = 0 ; j < n ; ++ j ) {
if ( grid [ i ][ j ] && ! p [ i ][ j ]) {
++ root ;
ans = max ( ans , dfs ( i , j ));
}
}
}
for ( int i = 0 ; i < n ; ++ i ) {
for ( int j = 0 ; j < n ; ++ j ) {
if ( ! grid [ i ][ j ]) {
unordered_set < int > s ;
for ( int k = 0 ; k < 4 ; ++ k ) {
int x = i + dirs [ k ];
int y = j + dirs [ k + 1 ];
if ( x >= 0 && x < n && y >= 0 && y < n ) {
s . insert ( p [ x ][ y ]);
}
}
int t = 1 ;
for ( int x : s ) {
t += cnt [ x ];
}
ans = max ( ans , t );
}
}
}
return ans ;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 func largestIsland ( grid [][] int ) int {
n := len ( grid )
p := make ([][] int , n )
for i := range p {
p [ i ] = make ([] int , n )
}
cnt := make ([] int , n * n + 1 )
dirs := [] int { - 1 , 0 , 1 , 0 , - 1 }
root := 0
ans := 0
var dfs func ( int , int ) int
dfs = func ( i , j int ) int {
p [ i ][ j ] = root
cnt [ root ] ++
for k := 0 ; k < 4 ; k ++ {
x := i + dirs [ k ]
y := j + dirs [ k + 1 ]
if x >= 0 && x < n && y >= 0 && y < n && grid [ x ][ y ] == 1 && p [ x ][ y ] == 0 {
dfs ( x , y )
}
}
return cnt [ root ]
}
for i := 0 ; i < n ; i ++ {
for j := 0 ; j < n ; j ++ {
if grid [ i ][ j ] == 1 && p [ i ][ j ] == 0 {
root ++
ans = max ( ans , dfs ( i , j ))
}
}
}
for i := 0 ; i < n ; i ++ {
for j := 0 ; j < n ; j ++ {
if grid [ i ][ j ] == 0 {
s := make ( map [ int ] struct {})
for k := 0 ; k < 4 ; k ++ {
x := i + dirs [ k ]
y := j + dirs [ k + 1 ]
if x >= 0 && x < n && y >= 0 && y < n {
s [ p [ x ][ y ]] = struct {}{}
}
}
t := 1
for x := range s {
t += cnt [ x ]
}
ans = max ( ans , t )
}
}
}
return ans
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 function largestIsland ( grid : number [][]) : number {
const n = grid . length ;
const p = Array . from ({ length : n }, () => Array ( n ). fill ( 0 ));
const cnt = Array ( n * n + 1 ). fill ( 0 );
const dirs = [ - 1 , 0 , 1 , 0 , - 1 ];
let root = 0 ;
let ans = 0 ;
const dfs = ( i : number , j : number ) : number => {
p [ i ][ j ] = root ;
cnt [ root ] ++ ;
for ( let k = 0 ; k < 4 ; ++ k ) {
const x = i + dirs [ k ];
const y = j + dirs [ k + 1 ];
if ( x >= 0 && x < n && y >= 0 && y < n && grid [ x ][ y ] === 1 && p [ x ][ y ] === 0 ) {
dfs ( x , y );
}
}
return cnt [ root ];
};
for ( let i = 0 ; i < n ; ++ i ) {
for ( let j = 0 ; j < n ; ++ j ) {
if ( grid [ i ][ j ] === 1 && p [ i ][ j ] === 0 ) {
root ++ ;
ans = Math . max ( ans , dfs ( i , j ));
}
}
}
for ( let i = 0 ; i < n ; ++ i ) {
for ( let j = 0 ; j < n ; ++ j ) {
if ( grid [ i ][ j ] === 0 ) {
const s = new Set < number > ();
for ( let k = 0 ; k < 4 ; ++ k ) {
const x = i + dirs [ k ];
const y = j + dirs [ k + 1 ];
if ( x >= 0 && x < n && y >= 0 && y < n ) {
s . add ( p [ x ][ y ]);
}
}
let t = 1 ;
for ( const x of s ) {
t += cnt [ x ];
}
ans = Math . max ( ans , t );
}
}
}
return ans ;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 use std :: collections :: HashSet ;
impl Solution {
pub fn largest_island ( grid : Vec < Vec < i32 >> ) -> i32 {
let n = grid . len ();
let mut p = vec! [ vec! [ 0 ; n ]; n ];
let mut cnt = vec! [ 0 ; n * n + 1 ];
let dirs = [ - 1 , 0 , 1 , 0 , - 1 ];
let mut root = 0 ;
let mut ans = 0 ;
fn dfs (
grid : & Vec < Vec < i32 >> ,
p : & mut Vec < Vec < i32 >> ,
cnt : & mut Vec < i32 > ,
root : i32 ,
i : usize ,
j : usize ,
dirs : & [ i32 ; 5 ],
) -> i32 {
p [ i ][ j ] = root ;
cnt [ root as usize ] += 1 ;
for k in 0 .. 4 {
let x = ( i as i32 ) + dirs [ k ];
let y = ( j as i32 ) + dirs [ k + 1 ];
if x >= 0
&& ( x as usize ) < grid . len ()
&& y >= 0
&& ( y as usize ) < grid . len ()
&& grid [ x as usize ][ y as usize ] == 1
&& p [ x as usize ][ y as usize ] == 0
{
dfs ( grid , p , cnt , root , x as usize , y as usize , dirs );
}
}
cnt [ root as usize ]
}
for i in 0 .. n {
for j in 0 .. n {
if grid [ i ][ j ] == 1 && p [ i ][ j ] == 0 {
root += 1 ;
ans = ans . max ( dfs ( & grid , & mut p , & mut cnt , root , i , j , & dirs ));
}
}
}
for i in 0 .. n {
for j in 0 .. n {
if grid [ i ][ j ] == 0 {
let mut s = HashSet :: new ();
for k in 0 .. 4 {
let x = ( i as i32 ) + dirs [ k ];
let y = ( j as i32 ) + dirs [ k + 1 ];
if x >= 0 && ( x as usize ) < n && y >= 0 && ( y as usize ) < n {
s . insert ( p [ x as usize ][ y as usize ]);
}
}
let mut t = 1 ;
for & x in & s {
t += cnt [ x as usize ];
}
ans = ans . max ( t );
}
}
}
ans
}
}