Depth-First Search
Breadth-First Search
Union Find
Array
Matrix
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
}
}