给你一个大小为 m x n
的二进制矩阵 grid
。
岛屿 是由一些相邻的 1
(代表土地) 构成的组合,这里的「相邻」要求两个 1
必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid
的四个边缘都被 0
(代表水)包围着。
岛屿的面积是岛上值为 1
的单元格的数目。
计算并返回 grid
中最大的岛屿面积。如果没有岛屿,则返回面积为 0
。
示例 1:
输入:grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]] 输出:6 解释:答案不应该是11
,因为岛屿只能包含水平或垂直这四个方向上的1
。
示例 2:
输入:grid = [[0,0,0,0,0,0,0,0]] 输出:0
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 50
grid[i][j]
为0
或1
方法一:DFS
方法二:并查集
并查集模板:
模板 1——朴素并查集:
# 初始化,p存储每个点的父节点
p = list(range(n))
# 返回x的祖宗节点
def find(x):
if p[x] != x:
# 路径压缩
p[x] = find(p[x])
return p[x]
# 合并a和b所在的两个集合
p[find(a)] = find(b)
模板 2——维护 size 的并查集:
# 初始化,p存储每个点的父节点,size只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量
p = list(range(n))
size = [1] * n
# 返回x的祖宗节点
def find(x):
if p[x] != x:
# 路径压缩
p[x] = find(p[x])
return p[x]
# 合并a和b所在的两个集合
if find(a) != find(b):
size[find(b)] += size[find(a)]
p[find(a)] = find(b)
模板 3——维护到祖宗节点距离的并查集:
# 初始化,p存储每个点的父节点,d[x]存储x到p[x]的距离
p = list(range(n))
d = [0] * n
# 返回x的祖宗节点
def find(x):
if p[x] != x:
t = find(p[x])
d[x] += d[p[x]]
p[x] = t
return p[x]
# 合并a和b所在的两个集合
p[find(a)] = find(b)
d[find(a)] = distance
DFS:
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
def dfs(i, j):
grid[i][j] = 0
ans = 1
for a, b in [[0, -1], [0, 1], [-1, 0], [1, 0]]:
x, y = i + a, j + b
if 0 <= x < m and 0 <= y < n and grid[x][y] == 1:
ans += dfs(x, y)
return ans
m, n = len(grid), len(grid[0])
return max([dfs(i, j) for i in range(m) for j in range(n) if grid[i][j] == 1], default=0)
并查集:
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
def find(x):
if p[x] != x:
p[x] = find(p[x])
return p[x]
m, n = len(grid), len(grid[0])
p = list(range(m * n))
size = [1] * (m * n)
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
for a, b in [[0, 1], [1, 0]]:
x, y = i + a, j + b
if 0 <= x < m and 0 <= y < n and grid[x][y] == 1 and find(i * n + j) != find(x * n + y):
size[find(x * n + y)] += size[find(i * n + j)]
p[find(i * n + j)] = find(x * n + y)
return max([size[i * n + j] for i in range(m) for j in range(n) if grid[i][j] == 1], default=0)
DFS:
class Solution {
private int[][] grid;
private int m;
private int n;
public int maxAreaOfIsland(int[][] grid) {
m = grid.length;
n = grid[0].length;
this.grid = grid;
int ans = 0;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == 1) {
ans = Math.max(ans, dfs(i, j));
}
}
}
return ans;
}
private int dfs(int i, int j) {
grid[i][j] = 0;
int[] dirs = {-1, 0, 1, 0, -1};
int ans = 1;
for (int k = 0; k < 4; ++k) {
int x = i + dirs[k];
int y = j + dirs[k + 1];
if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1) {
ans += dfs(x, y);
}
}
return ans;
}
}
并查集:
class Solution {
private int[] p;
private int[] size;
public int maxAreaOfIsland(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
p = new int[m * n];
size = new int[m * n];
for (int i = 0; i < p.length; ++i) {
p[i] = i;
size[i] = 1;
}
int[] dirs = {0, 1, 0};
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == 1) {
for (int k = 0; k < 2; ++k) {
int x = i + dirs[k];
int y = j + dirs[k + 1];
if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1
&& find(i * n + j) != find(x * n + y)) {
size[find(x * n + y)] += size[find(i * n + j)];
p[find(i * n + j)] = find(x * n + y);
}
}
}
}
}
int ans = 0;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == 1) {
ans = Math.max(ans, size[i * n + j]);
}
}
}
return ans;
}
private int find(int x) {
if (p[x] != x) {
p[x] = find(p[x]);
}
return p[x];
}
}
DFS:
function maxAreaOfIsland(grid: number[][]): number {
const m = grid.length;
const n = grid[0].length;
let ans = 0;
const dirs = [-1, 0, 1, 0, -1];
let dfs = function (i, j) {
grid[i][j] = 0;
let ans = 1;
for (let k = 0; k < 4; ++k) {
const x = i + dirs[k];
const y = j + dirs[k + 1];
if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1) {
ans += dfs(x, y);
}
}
return ans;
};
for (let i = 0; i < m; ++i) {
for (let j = 0; j < n; ++j) {
if (grid[i][j] == 1) {
ans = Math.max(ans, dfs(i, j));
}
}
}
return ans;
}
并查集:
function maxAreaOfIsland(grid: number[][]): number {
const m = grid.length;
const n = grid[0].length;
let p = new Array(m * n);
for (let i = 0; i < p.length; ++i) {
p[i] = i;
}
let size = new Array(m * n).fill(1);
let find = function (x) {
if (p[x] != x) {
p[x] = find(p[x]);
}
return p[x];
};
const dirs = [1, 0, 1];
for (let i = 0; i < m; ++i) {
for (let j = 0; j < n; ++j) {
if (grid[i][j] == 1) {
for (let k = 0; k < 2; ++k) {
const x = i + dirs[k];
const y = j + dirs[k + 1];
if (
x >= 0 &&
x < m &&
y >= 0 &&
y < n &&
grid[x][y] == 1 &&
find(x * n + y) != find(i * n + j)
) {
size[find(x * n + y)] += size[find(i * n + j)];
p[find(i * n + j)] = find(x * n + y);
}
}
}
}
}
let ans = 0;
for (let i = 0; i < m; ++i) {
for (let j = 0; j < n; ++j) {
if (grid[i][j] == 1) {
ans = Math.max(ans, size[i * n + j]);
}
}
}
return ans;
}
DFS:
class Solution {
public:
int m;
int n;
int maxAreaOfIsland(vector<vector<int>>& grid) {
m = grid.size();
n = grid[0].size();
int ans = 0;
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
if (grid[i][j] == 1)
ans = max(ans, dfs(i, j, grid));
return ans;
}
int dfs(int i, int j, vector<vector<int>>& grid) {
grid[i][j] = 0;
int ans = 1;
vector<int> dirs = {-1, 0, 1, 0, -1};
for (int k = 0; k < 4; ++k) {
int x = i + dirs[k];
int y = j + dirs[k + 1];
if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1)
ans += dfs(x, y, grid);
}
return ans;
}
};
并查集:
class Solution {
public:
vector<int> p;
vector<int> size;
int maxAreaOfIsland(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
p.resize(m * n);
size.resize(m * n, 1);
for (int i = 0; i < p.size(); ++i) p[i] = i;
vector<int> dirs = {0, 1, 0};
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < n; ++j)
{
if (grid[i][j])
{
for (int k = 0; k < 2; ++k)
{
int x = i + dirs[k];
int y = j + dirs[k + 1];
if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] && find(i * n + j) != find(x * n + y))
{
size[find(x * n + y)] += size[find(i * n + j)];
p[find(i * n + j)] = find(x * n + y);
}
}
}
}
}
int ans = 0;
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
if (grid[i][j])
ans = max(ans, size[i * n + j]);
return ans;
}
int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
};
DFS:
func maxAreaOfIsland(grid [][]int) int {
m, n := len(grid), len(grid[0])
dirs := []int{-1, 0, 1, 0, -1}
var dfs func(i, j int) int
dfs = func(i, j int) int {
grid[i][j] = 0
ans := 1
for k := 0; k < 4; k++ {
x, y := i+dirs[k], j+dirs[k+1]
if x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 {
ans += dfs(x, y)
}
}
return ans
}
ans := 0
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if grid[i][j] == 1 {
ans = max(ans, dfs(i, j))
}
}
}
return ans
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
并查集:
func maxAreaOfIsland(grid [][]int) int {
m, n := len(grid), len(grid[0])
p := make([]int, m*n)
size := make([]int, m*n)
for i := range p {
p[i] = i
size[i] = 1
}
var find func(x int) int
find = func(x int) int {
if p[x] != x {
p[x] = find(p[x])
}
return p[x]
}
dirs := []int{1, 0, 1}
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if grid[i][j] == 1 {
for k := 0; k < 2; k++ {
x, y := i+dirs[k], j+dirs[k+1]
if x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && find(i*n+j) != find(x*n+y) {
size[find(x*n+y)] += size[find(i*n+j)]
p[find(i*n+j)] = find(x*n + y)
}
}
}
}
}
ans := 0
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if grid[i][j] == 1 {
ans = max(ans, size[i*n+j])
}
}
}
return ans
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
DFS:
impl Solution {
fn dfs(grid: &mut Vec<Vec<i32>>, i: usize, j: usize) -> i32 {
if i == grid.len() || j == grid[0].len() || grid[i][j] == 0 {
return 0;
}
grid[i][j] = 0;
let mut res = 1 + Self::dfs(grid, i + 1, j) + Self::dfs(grid, i, j + 1);
if i != 0 {
res += Self::dfs(grid, i - 1, j)
}
if j != 0 {
res += Self::dfs(grid, i, j - 1)
}
res
}
pub fn max_area_of_island(mut grid: Vec<Vec<i32>>) -> i32 {
let m = grid.len();
let n = grid[0].len();
let mut res = 0;
for i in 0..m {
for j in 0..n {
res = res.max(Self::dfs(&mut grid, i, j))
}
}
res
}
}