Open azl397985856 opened 2 years ago
深度优先遍历。
从遇到的每个陆地出发,深度优先遍历相邻,发现陆地就累加。直到所有的相邻都是水。标记所有访问过的格子。
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
r = len(grid)
c = len(grid[0])
visited = [[False] * c for _ in range(r)]
res = 0
def count(i: int, j: int) -> int:
if visited[i][j]: return 0
visited[i][j] = True
if grid[i][j] == 0: return 0
area = 1
if 0 <= i - 1 < r:
area += count(i - 1, j)
if 0 <= i + 1 < r:
area += count(i + 1, j)
if 0 <= j - 1 < c:
area += count(i, j - 1)
if 0 <= j + 1 < c:
area += count(i, j + 1)
return area
for i in range(r):
for j in range(c):
res = max(res, count(i, j))
return res
时间复杂度 O(mxn)
空间复杂度 O(mxn)
思路 dfs, 每个格子踩一次就沉,所以不用担心重复,直接改grid也可以节省空间到 O(1)
代码
class Solution:
def largestLand(self, grid: List[List[int]]) -> int:
rows = len(grid)
cols = len(grid[0])
res = 0
def find_neib(row, col, neibs):
for r, c in [(row+1,col),(row-1,col),(row,col+1),(row,col-1)]:
if r >= 0 and r < rows and c >= 0 and c < cols:
if grid[r][c] == 1:
grid[r][c] = 0
neibs += 1
neibs += find_neib(r, c, neibs)
return neibs
for row in range(rows):
for col in range(cols):
if grid[row][col] == 1:
gird[row][col] = 0
res = max(res, find_neib(row, col, 1))
return res
复杂度 时间 O(r*c) 空间 O(1)
class Solution { public int maxAreaOfIsland(int[][] grid) { int max = 0; for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[0].length; j++) { max = Math.max(max, dfs(grid, i, j)); } } return max; }
private int dfs(int[][] grid, int i, int j) {
if (i < 0 || j < 0 || i >= grid.length || j >=grid[0].length || grid[i][j] == 0) {
return 0;
}
grid[i][j] = 0;
int count = 1;
count += dfs(grid, i+1, j);
count += dfs(grid, i-1, j);
count += dfs(grid, i, j+1);
count += dfs(grid, i, j-1);
return count;
}
}
# dfs
# time: O(m*n)
# space: O(m*n)
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
res = 0
rows = len(grid)
cols = len(grid[0])
visited = [[0 for i in range(cols)] for j in range(rows)]
def dfs(i, j, visited):
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]
visited[i][j] = 1
count = 1
for k in range(4):
new_i = i + dx[k]
new_j = j + dy[k]
if new_i <= rows - 1 and new_i >= 0 and new_j <= cols - 1 and new_j >= 0 and visited[new_i][new_j] == 0 and grid[new_i][new_j] == 1:
count += dfs(new_i, new_j, visited)
return count
for i in range(rows):
for j in range(cols):
if visited[i][j] == 0 and grid[i][j] == 1:
res = max(dfs(i, j, visited), res)
return res
var maxAreaOfIsland = function(grid) { let x=grid[0].length,y=grid.length; let res=0; function dfs(i,j){ // i 是 y ,j 是 x if(i>=y||j>=x||j<0||i<0||grid[i][j]!=1)return 0; grid[i][j]=-1; return 1+dfs(i+1,j)+dfs(i-1,j)+dfs(i,j-1)+dfs(i,j+1);
}
for(let i=0;i<y;i++){
// i 是 y ,j 是 x
for(let j=0;j<x;j++){
if(grid[i][j]){
res=Math.max(res, dfs(i,j))
}
}
}
return res
};
DFS
var maxAreaOfIsland = function(grid) {
let row = grid.length, col = grid[0].length
function dfs(x, y) {
if(x < 0 || x >= row || y < 0 || y >= col || grid[x][y] === 0) return 0
grid[x][y] = 0
let ans = 1, dx = [-1, 1, 0, 0], dy = [0, 0, 1, -1]
for(let i = 0; i < dx.length; i++) {
ans += dfs(x + dx[i], y + dy[i])
}
return ans
}
let res = 0
for(let i = 0; i < row; i++) {
for(let j = 0; j < col; j++) {
res = Math.max(res, dfs(i, j))
}
}
return res
};
思路 深度优先遍历。
从遇到的每个陆地出发,深度优先遍历相邻,发现陆地就累加。直到所有的相邻都是水。标记所有访问过的格子。
代码 class Solution: def maxAreaOfIsland(self, grid: List[List[int]]) -> int: r = len(grid) c = len(grid[0])
visited = [[False] * c for _ in range(r)]
res = 0
def count(i: int, j: int) -> int:
if visited[i][j]: return 0
visited[i][j] = True
if grid[i][j] == 0: return 0
area = 1
if 0 <= i - 1 < r:
area += count(i - 1, j)
if 0 <= i + 1 < r:
area += count(i + 1, j)
if 0 <= j - 1 < c:
area += count(i, j - 1)
if 0 <= j + 1 < c:
area += count(i, j + 1)
return area
for i in range(r):
for j in range(c):
res = max(res, count(i, j))
return res
时间复杂度 O(mxn)
空间复杂度 O(mxn)
class Solution(object): def maxAreaOfIsland(self, grid): """ :type grid: List[List[int]] :rtype: int """ res = 0 m = len(grid) n = len(grid[0])
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
res = max(res, self.dfs(grid, i, j))
return res
def dfs(self, grid, i, j):
m = len(grid)
n = len(grid[0])
if i < 0 or j < 0 or i >= m or j >= n:
return 0
if grid[i][j] == 0:
return 0
grid[i][j] = 0
return self.dfs(grid, i+1, j) + self.dfs(grid, i-1, j) + self.dfs(grid, i, j+1) + self.dfs(grid, i, j-1) + 1
思路
代码
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
m, n = len(grid), len(grid[0])
ans = 0
def dfs(i, j):
if i < 0 or i >= m or j < 0 or j >= n:
return 0
if grid[i][j] == 0:
return 0
grid[i][j] = 0
top = dfs(i+1, j)
bottom = dfs(i-1, j)
left = dfs(i, j-1)
right = dfs(i, j+1)
return 1 + sum([top, bottom, left, right])
for i in range(m):
for j in range(n):
ans = max(ans, dfs(i, j))
return ans
复杂度分析
def island_area(grid):
if not grid:
return 0
nrow = len(grid)
ncol = len(grid[0])
if nrow == 0 or ncol == 0:
return 0
def dfs(row, col):
nonlocal area
nonlocal nrow
nonlocal ncol
if grid[row][col] == 0:
return
else:
area += 1
grid[row][col] = 0
if row >= 1:
dfs(row - 1, col)
if row <= nrow - 2:
dfs(row + 1, col)
if col >= 1:
dfs(row, col - 1)
if col <= ncol - 2:
dfs(row, col + 1)
return
result = 0
for row in range(nrow):
for col in range(ncol):
if grid[row][col] != 1:
continue
area = 0
dfs(row, col)
result = max(result, area)
return result
time complexity: O(m x n), m is number of rows, n is number of columns space complexity: O(m x n)
func maxAreaOfIsland(grid [][]int) int {
out := 0
m := len(grid)
if m == 0{
return 0
}
n := len(grid[0])
var dfs func(row int,col int) int
dfs = func(row int,col int) int{
if row < 0 || row >= m || col < 0 || col >= n ||grid[row][col] == 0{
return 0
}
grid[row][col] = 0
return 1 +dfs(row+1,col)+dfs(row-1,col)+dfs(row,col+1)+dfs(row,col-1)
}
for i:=0;i<m;i++{
for j:=0;j<n;j++{
if grid[i][j] == 1{
out = max(out,dfs(i,j))
}
}
}
return out
}
func max(a,b int) int{
if a > b{
return a
}
return b
}
时间复杂度O(MN) 空间复杂度O(MN)
DFS
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int maxArea = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
maxArea = Math.max(maxArea, dfs(grid,i,j));
}
}
return maxArea;
}
public int dfs (int[][] grid, int i, int j) {
if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] == 0) {
return 0;
}
//Overwrite (i,j) as 0, mark as visited
grid[i][j] = 0;
return 1 + dfs(grid, i + 1, j) + dfs(grid, i, j + 1) + dfs(grid, i - 1, j) + dfs(grid, i, j - 1);
}
}
非递归DFS
class Solution {
public int maxAreaOfIsland(int[][] grid) {
// Non-recursive DFS
int maxArea = 0;
Deque<int[]> stack = new LinkedList<>();
//Stack was used to save position {x,y} indexs
int[][] idxArr = {{-1, 0}, {1, 0}, {0, 1},{0, -1}};
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
stack.push(new int[]{i, j});
int curArea = 0;
while (!stack.isEmpty()) {
int[] pop = stack.pop();
int curI = pop[0];
int curJ = pop[1];
if (curI < 0 || curJ < 0 || curI >= grid.length || curJ >= grid[0].length || grid[curI][curJ] == 0) {
continue;
}
curArea++;
grid[curI][curJ] = 0;
for (int[] idx : idxArr) {
stack.push(new int[]{curI + idx[0], curJ + idx[1]});
}
}
maxArea = Math.max(maxArea, curArea);
}
}
return maxArea;
}
}
BFS
class Solution {
public int maxAreaOfIsland(int[][] grid) {
// Non-recursive DFS
int maxArea = 0;
Deque<int[]> queue = new LinkedList<>();
//Stack was used to save position {x,y} indexs
int[][] idxArr = {{-1, 0}, {1, 0}, {0, 1},{0, -1}};
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
queue.offer(new int[]{i, j});
int curArea = 0;
while (!queue.isEmpty()) {
int[] poll = queue.poll();
int curI = poll[0];
int curJ = poll[1];
if (curI < 0 || curJ < 0 || curI >= grid.length || curJ >= grid[0].length || grid[curI][curJ] == 0) {
continue;
}
curArea++;
grid[curI][curJ] = 0;
for (int[] idx : idxArr) {
queue.offer(new int[]{curI + idx[0], curJ + idx[1]});
}
}
maxArea = Math.max(maxArea, curArea);
}
}
return maxArea;
}
}
func maxAreaOfIsland(grid [][]int) int {
out := 0
//m为行数
m := len(grid)
if m == 0{
return 0
}
//n为列数
n := len(grid[0])
//dfs如果遇到边界或者此处是海洋,那么就返回0
//反之将此处设为海洋,避免多次访问。返回的是上下左右的面积加上1(上下左右的面积加上自己的面积就是总面积)
var dfs func(row int,col int) int
dfs = func(row int,col int) int{
if row < 0 || row >= m || col < 0 || col >= n ||grid[row][col] == 0{
return 0
}
grid[row][col] = 0
return 1 +dfs(row+1,col)+dfs(row-1,col)+dfs(row,col+1)+dfs(row,col-1)
}
for i:=0;i<m;i++{
for j:=0;j<n;j++{
if grid[i][j] == 1{
out = max(out,dfs(i,j))
}
}
}
return out
}
func max(a,b int) int{
if a > b{
return a
}
return b
}
时间复杂度:O(mn) 空间复杂度:O(mn)
C++ Code:
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int n = grid.size();
int m = grid[0].size();
int ret =0;
for(int i=0; i< n; i++)
{
for(int j=0; j< m; j++)
{
if(grid[i][j]==1)
{
int iSize =0;
grid[i][j] =0;
dfs(grid, i, j, iSize);
ret = max(ret, iSize);
}
}
}
return ret;
}
void dfs(vector<vector<int>>& grid, int row, int col, int & ret)
{
vector<int> direction = {-1, 0, 1, 0, -1};
ret++;
for(int i=0; i< direction.size()-1; i++)
{
int irow = row + direction[i];
int icol = col + direction[i+1];
if(irow>=grid.size() || irow<0 || icol >=grid[0].size() || icol<0)
continue;
if(grid[irow][icol])
{
grid[irow][icol] =0;
dfs(grid, irow, icol, ret);
}
}
}
};
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
m, n = len(grid), len(grid[0])
ans = 0
def dfs(i, j):
if i < 0 or i >= m or j < 0 or j >= n:
return 0
if grid[i][j] == 0:
return 0
grid[i][j] = 0
top = dfs(i+1, j)
bottom = dfs(i-1, j)
left = dfs(i, j-1)
right = dfs(i, j+1)
return 1 + sum([top, bottom, left, right])
for i in range(m):
for j in range(n):
ans = max(ans, dfs(i, j))
return ans
小岛问题模板题
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int maxArea = 0;
for (int i=0; i<m; i++) {
for (int j=0; j<n; j++) {
if (grid[i][j] == 1) {
maxArea = Math.max(maxArea, dfs(grid, i, j));
}
}
}
return maxArea;
}
int[] dx = new int[] {1, 0, -1, 0};
int[] dy = new int[] {0, 1, 0, -1};
private int dfs(int[][] grid, int row, int col) {
int count = 0;
int m = grid.length;
int n = grid[0].length;
if (grid[row][col] == 1) {
++count;
grid[row][col] = 2;
for (int i=0; i<4; i++) {
int newRow = row + dx[i];
int newCol = col + dy[i];
if (newRow >= 0 && newRow < m && newCol >= 0 && newCol < n) {
count += dfs(grid, newRow, newCol);
}
}
}
return count;
}
}
TC: O(mn) SC: O(mn)
深度优先:
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ROWS, COLUMNS = len(grid), len(grid[0])
visit = set()
def dfs(row, col):
# check if it's out of bound
if (row < 0 or row == ROWS or col < 0 or col == COLUMNS or
grid[row][col] == 0 or (row, col) in visit):
return 0
# add visited pair of row and col to the hashset
visit.add((row, col))
# calculate the area, in four direction
return (1 + dfs(row + 1, col) +
dfs(row - 1, col) +
dfs(row, col + 1) +
dfs(row, col - 1))
area = 0
for row in range(ROWS):
for col in range(COLUMNS):
area = max(area, dfs(row, col))
return area
C++ Code:
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int n = grid.size();
int m = grid[0].size();
int ret =0;
for(int i=0; i< n; i++)
{
for(int j=0; j< m; j++)
{
if(grid[i][j]==1)
{
int iSize =0;
grid[i][j] =0;
dfs(grid, i, j, iSize);
ret = max(ret, iSize);
}
}
}
return ret;
}
void dfs(vector<vector<int>>& grid, int row, int col, int & ret)
{
vector<int> direction = {-1, 0, 1, 0, -1};
ret++;
for(int i=0; i< direction.size()-1; i++)
{
int irow = row + direction[i];
int icol = col + direction[i+1];
if(irow>=grid.size() || irow<0 || icol >=grid[0].size() || icol<0)
continue;
if(grid[irow][icol])
{
grid[irow][icol] =0;
dfs(grid, irow, icol, ret);
}
}
}
};
思路
深度优先搜索,套模板即可。
代码
class Solution {
int[][] grid;
boolean[][] visited;
int m,n;
int count(int i,int j){
if(this.visited[i][j] == true){
return 0;
}
this.visited[i][j] = true;
if(this.grid[i][j] == 0){
return 0;
}
int area = 1;
if(i - 1 >= 0 && i - 1 < m){
area += count(i - 1,j);
}
if(i + 1 >= 0 && i + 1 < m){
area += count(i + 1,j);
}
if(j - 1 >= 0 && j - 1 < n){
area += count(i, j - 1);
}
if(j + 1 >= 0 && j + 1 < n){
area += count(i, j + 1);
}
return area;
}
public int maxAreaOfIsland(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
boolean[][] visited = new boolean[m][n];
this.grid = grid;
this.m = m;
this.n = n;
for(int i = 0;i < m;i++){
for(int j = 0;j < n;j++){
visited[i][j] = false;
}
}
this.visited = visited;
int res = 0;
for(int i = 0;i < m;i++){
for(int j = 0;j < n;j++){
res = Math.max(res,count(i, j));
}
}
return res;
}
}
复杂度分析
时间复杂度:O(mn)
空间复杂度: O(mn)
DFS
public int maxAreaOfIsland(int[][] grid) {
int max = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
max = Math.max(max, helper(grid, i, j));
}
}
}
return max;
}
public int helper(int[][] grid, int i, int j) {
if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0) {
return 0;
}
grid[i][j] = 0;
return 1 + helper(grid, i - 1, j) + helper(grid, i + 1, j) + helper(grid, i, j - 1) + helper(grid, i, j + 1);
}
const dfs = (grid, i, j) => {
let m = grid.length,
n = grid[0].length;
if (i < 0 || j < 0 || i >= m || j >= n) {
// 超出索引边界
return 0;
}
if (grid[i][j] == 0) {
// 已经是海水了
return 0;
}
// 将 (i, j) 变成海水
grid[i][j] = 0;
// 淹没上下左右的陆地
return (
dfs(grid, i + 1, j) + // 上
dfs(grid, i - 1, j) + // 下
dfs(grid, i, j - 1) + // 左
dfs(grid, i, j + 1) + // 右
1
);
};
/**
* @param {number[][]} grid
* @return {number}
*/
var maxAreaOfIsland = function (grid) {
let m = grid.length,
n = grid[0].length;
// 记录岛屿的最大面积
let count = 0;
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] == 1) {
// 淹没岛屿,并更新最大岛屿面积
count = Math.max(count, dfs(grid, i, j));
}
}
}
return count;
};
DFS: 每个格子试一遍,如果是1那就dfs搜索相邻位置,每搜一个就把这个格子置0表示visited。复杂度$O(m*n)$
class Solution:
# DFS: 每个格子试一遍,如果是1那就dfs搜索相邻位置,每搜一个就把这个格子置0表示visited。复杂度$O(m*n)$
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
m, n = len(grid), len(grid[0])
def dfs(i, j):
cnt = 1
grid[i][j] = 0
for dx, dy in directions:
x, y = i + dx, j + dy
if 0 <= x < m and 0 <= y < n and grid[x][y] == 1:
cnt += dfs(x, y)
return cnt
ans = 0
for i, j in product(range(len(grid)), range(len(grid[0]))):
if grid[i][j] == 1:
ans = max(ans, dfs(i, j))
return ans
islands
class Solution {
int[][] dirs = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
public int maxAreaOfIsland(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int count = 0;
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(grid[i][j] == 1){
count = Math.max(count, dfs(i, j, grid));
}
}
}
return count;
}
int dfs(int i, int j, int[][] grid){
if(i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] == 0){
return 0;
}
grid[i][j] = 0;
int num = 1;
for(int[] dir : dirs){
int x = i + dir[0], y = j + dir[1];
num += dfs(x, y, grid);
}
return num;
}
}
复杂度分析
DFS+STACK
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int ans = 0;
for (int i = 0; i != grid.size(); ++i) {
for (int j = 0; j != grid[0].size(); ++j) {
int cur = 0;
stack<int> stacki;
stack<int> stackj;
stacki.push(i);
stackj.push(j);
while (!stacki.empty()) {
int cur_i = stacki.top(), cur_j = stackj.top();
stacki.pop();
stackj.pop();
if (cur_i < 0 || cur_j < 0 || cur_i == grid.size() || cur_j == grid[0].size() || grid[cur_i][cur_j] != 1) {
continue;
}
++cur;
grid[cur_i][cur_j] = 0;
int di[4] = {0, 0, 1, -1};
int dj[4] = {1, -1, 0, 0};
for (int index = 0; index != 4; ++index) {
int next_i = cur_i + di[index], next_j = cur_j + dj[index];
stacki.push(next_i);
stackj.push(next_j);
}
}
ans = max(ans, cur);
}
}
return ans;
}
};
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
visited = set()
res = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == 1:
tmp = self.dfs(grid, i, j, visited)
res = max(res, tmp)
return res
def isValid(self, grid, i, j, visited):
if 0<=i<len(grid) and 0<=j<len(grid[0]) and (i, j) not in visited and grid[i][j]==1:
return True
else:
return False
def dfs(self, grid, i, j, visited):
visited.add((i, j))
area = 1
for ii, jj in [(i+1, j), (i-1, j), (i, j-1), (i, j+1)]:
if self.isValid(grid, ii, jj, visited):
area += self.dfs(grid, ii, jj, visited)
return area
TC: O(MN) SC: O(MN)
思路
深度优先搜索,经过该岛之后,计数加一,并标记为已经访问过。
代码
var maxAreaOfIsland = function (grid) {
let maxArea = 0, area = 0;
let m = grid.length, n = grid[0].length;
let visited = new Set();
function dfs(row, col){
if(row < 0 || row >= m || col < 0 || col >= n
|| !grid[row][col] || visited.has(row + "," + col)) return;
visited.add(row + "," + col);
area++;
dfs(row + 1, col);
dfs(row - 1, col);
dfs(row, col + 1);
dfs(row, col - 1);
};
for(let i = 0; i < m; i++){
for(let j = 0; j < n; j++){
dfs(i, j);
maxArea = Math.max(area, maxArea);
area = 0;
}
};
return maxArea;
};
复杂度分析
给你一个大小为 m x n 的二进制矩阵 grid 。
岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。
岛屿的面积是岛上值为 1 的单元格的数目。
计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。
DFS即可
对数组进行遍历,当值不为0时对其进行dfs操作,使用search数组记录是否遍历过。
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int max = 0;
//创建search数组
boolean[][] search = new boolean[grid.length][grid[0].length];
for (int i = 0; i < grid.length; ++i) {
//填充数组
Arrays.fill(search[i], true);
}
for (int i = 0; i < grid.length; ++i) {
for (int j = 0; j < grid[0].length; ++j) {
//如果值大于0,且没被遍历过,就dfs它
if (grid[i][j] > 0 && search[i][j]) {
int num = dfs(grid, i, j, search);
max = max > num ? max : num;
}
}
}
return max;
}
//dfs
int dfs(int[][] grid, int i, int j, boolean[][] search) {
search[i][j] = false;
int n = grid.length - 1;
int m = grid[0].length - 1;
int num = 1;
if (i > 0) {
if (grid[i - 1][j] > 0 && search[i - 1][j]) {
num += dfs(grid, i - 1, j, search);
}
}
if (j > 0) {
if (grid[i][j - 1] > 0 && search[i][j - 1]) {
num += dfs(grid, i, j - 1, search);
}
}
if (i < n) {
if (grid[i + 1][j] > 0 && search[i + 1][j]) {
num += dfs(grid, i + 1, j, search);
}
}
if (j < m) {
if (grid[i][j + 1] > 0 && search[i][j + 1]) {
num += dfs(grid, i, j + 1, search);
}
}
return num;
}
}
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
r = len(grid)
c = len(grid[0])
visited = [[False] * c for _ in range(r)]
res = 0
def count(i: int, j: int) -> int:
if visited[i][j]: return 0
visited[i][j] = True
if grid[i][j] == 0: return 0
area = 1
if 0 <= i - 1 < r:
area += count(i - 1, j)
if 0 <= i + 1 < r:
area += count(i + 1, j)
if 0 <= j - 1 < c:
area += count(i, j - 1)
if 0 <= j + 1 < c:
area += count(i, j + 1)
return area
for i in range(r):
for j in range(c):
res = max(res, count(i, j))
return res
BFS or DFS
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int ans = 0;
for (int i = 0; i != grid.length; ++i) {
for (int j = 0; j != grid[0].length; ++j) {
ans = Math.max(ans, dfs(grid, i, j));
}
}
return ans;
}
public int dfs(int[][] grid, int cur_i, int cur_j) {
if (cur_i < 0 || cur_j < 0 || cur_i == grid.length || cur_j == grid[0].length || grid[cur_i][cur_j] != 1) {
return 0;
}
grid[cur_i][cur_j] = 0;
int[] di = {0, 0, 1, -1};
int[] dj = {1, -1, 0, 0};
int ans = 1;
for (int index = 0; index != 4; ++index) {
int next_i = cur_i + di[index], next_j = cur_j + dj[index];
ans += dfs(grid, next_i, next_j);
}
return ans;
}
}
Time O(N) Space O(N)
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
rows, cols = len(grid), len(grid[0])
ans = 0
'''
def dfs(row, col):
area = 0
if grid[row][col] == 1:
area += 1
grid[row][col] = 0
for nr, nc in [(row + 1, col), (row - 1, col), (row, col + 1), (row, col - 1)]:
if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == 1:
area += dfs(nr, nc)
return area
for row in range(rows):
for col in range(cols):
ans = max(ans, dfs(row, col))
return ans
'''
for row in range(rows):
for col in range(cols):
if grid[row][col] == 1:
queue = [(row, col)]
grid[row][col] = 0
area = 0
while queue:
cr, cc = queue.pop()
area += 1
for nr, nc in [(cr + 1, cc), (cr - 1, cc), (cr, cc + 1), (cr, cc - 1)]:
if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == 1:
queue.append((nr, nc))
grid[nr][nc] = 0
ans = max(ans, area)
return ans
``` Time complexity for dfs O(m*n*maximum area of islands)
Space complexity for dfs O(1)
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
rows, cols = len(grid), len(grid[0])
ans = 0
for row in range(rows):
for col in range(cols):
if grid[row][col] == 1:
area = 0
queue = deque([(row, col)])
grid[row][col] = 0
while queue:
row, col = queue.pop()
area += 1
for nr, nc in [(row + 1, col), (row - 1, col), (row, col + 1), (row, col -1)]:
if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == 1:
queue.append((nr, nc))
grid[nr][nc] = 0
ans = max(ans, area)
return ans
var maxAreaOfIsland = function(grid) {
let x=grid[0].length,y=grid.length;
let res=0;
function dfs(i,j){
// i 是 y ,j 是 x
if(i>=y||j>=x||j<0||i<0||grid[i][j]!=1)return 0;
grid[i][j]=-1;
return 1+dfs(i+1,j)+dfs(i-1,j)+dfs(i,j-1)+dfs(i,j+1);
}
for(let i=0;i<y;i++){
// i 是 y ,j 是 x
for(let j=0;j<x;j++){
if(grid[i][j]){
res=Math.max(res, dfs(i,j))
}
}
}
return res
};
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
m , n = len(grid) , len(grid[0])
vis = set()
def dfs(x , y ):
if x < 0 or x >= m or y < 0 or y >= n or (x , y) in vis:
return 0
vis.add((x,y))
return 1 + dfs(x + 1 , y) + dfs(x - 1 , y) + dfs(x ,y + 1) + dfs(x , y - 1)
for i in range(m):
for j in range(n):
if not grid[i][j]:
vis.add((i,j))
res = 0
for i in range(m):
for j in range(n):
if grid[i][j] and (i , j) not in vis:
res = max(res , dfs(i , j))
return res
class Solution {
public:
int m;
int n;
vector<vector<int>> direct = {{1,0},{-1,0},{0,-1},{0,1}};
int maxAreaOfIsland(vector<vector<int>>& grid) {
int max_area = 0;
this->m = grid.size();
this->n= grid[0].size();
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if(grid[i][j]==1){
max_area = max(max_area,dfs(i,j,grid));
}
}
}
return max_area;
}
int dfs(int x,int y,vector<vector<int>>& grid){
if(!isInArea(x,y)||grid[x][y]!=1)return 0;
grid[x][y] = -1;
int area =1;
for (auto & d:direct){
int newX= x+d[0];
int newY =y+ d[1];
area+= dfs(newX,newY,grid);
}
return area;
}
bool isInArea(int x, int y){
return x>=0&&y>=0&&x<m&&y<n;
}
};
class Solution { public int maxAreaOfIsland(int[][] grid) { int ans = 0; for (int i = 0; i != grid.length; ++i) { for (int j = 0; j != grid[0].length; ++j) { ans = Math.max(ans, dfs(grid, i, j)); } } return ans; }
public int dfs(int[][] grid, int cur_i, int cur_j) {
if (cur_i < 0 || cur_j < 0 || cur_i == grid.length || cur_j == grid[0].length || grid[cur_i][cur_j] != 1) {
return 0;
}
grid[cur_i][cur_j] = 0;
int[] di = {0, 0, 1, -1};
int[] dj = {1, -1, 0, 0};
int ans = 1;
for (int index = 0; index != 4; ++index) {
int next_i = cur_i + di[index], next_j = cur_j + dj[index];
ans += dfs(grid, next_i, next_j);
}
return ans;
}
}
DFS 递归。
对 grid 中的每一个点,我们查看它是否为 1。如果是的话,我们就继续查看和其相连的其他点,直到碰到非土地。
因为题目没有要求保留 grid,我们可以在每次碰到一块土地的时候就将其设为 0,从而防止重复访问。
CPP
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
// dfs
int ans = 0;
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
ans = max(ans, dfs(grid, i, j));
}
}
return ans;
}
private:
int dfs(vector<vector<int>>& grid, int row, int col)
{
if (row < 0 || col < 0 || row >= grid.size() || col >= grid[0].size() || grid[row][col] != 1) {
return 0;
}
int ans = 1;
grid[row][col] = 0; // prevent re-visit
int v[]{1, -1, 0, 0}; // go down, up, right, left
int h[]{0, 0, 1, -1};
for (int i = 0; i < 4; i++) {
ans += dfs(grid, row+v[i], col+h[i]);
}
return ans;
}
};
复杂度分析
//1-30 cpp
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int res = 0;
for (int i = 0; i < grid.size(); ++i) {
for (int j = 0; j < grid[0].size(); ++j) {
if (grid[i][j] == 1) {
int a = dfs(grid, i, j);
res = max(res, a);
}
}
}
return res;
}
int dfs(vector<vector<int>> &grid, int row, int col) {
if(!ingrid(grid, row, col)) {
return 0;
}
if (grid[row][col] != 1) {
return 0;
}
grid[row][col] = 2;
return 1+dfs(grid, row-1, col) + dfs(grid, row+1,col) +
dfs(grid,row,col-1) + dfs(grid,row,col+1);
}
bool ingrid(vector<vector<int>> &grid, int row, int col) {
return row>=0 && col>=0 && row<grid.size() && col<grid[0].size();
}
};
二维数组的DFS已经有非常成熟的框架了,主要是这一题可以通过改变值的方式来避开visited,就是把遍历过的1改成0,其他倒是没啥好说的
class Solution {
public:
int DFS(vector<vector<int>>& grid,int row,int col){
int lenrow = grid.size();
int lencol = grid[0].size();
if(row<0||row>=lenrow||col<0||col>=lencol||grid[row][col]==0) return 0;
grid[row][col] = 0;
return 1+DFS(grid,row-1,col)+DFS(grid,row+1,col)+DFS(grid,row,col-1)+DFS(grid,row,col+1);
}
int maxAreaOfIsland(vector<vector<int>>& grid) {
int res = 0;
int rowlen = grid.size();
int collen = grid[0].size();
for(int i = 0;i<rowlen;i++){
for(int j = 0;j<collen;j++){
res = max(res,DFS(grid,i,j));
}
}
return res;
}
};
复杂度分析
时间复杂度:O(m*n)
空间复杂度:O(m*n)
Day 【50】695. 岛屿的最大面积
广度优先搜索
思考 什么时候area增加面积
时间复杂度:O(rows*cols)。
其中 rows 是给定网格中的行数,cols 是列数。我们访问每个网格最多一次。
空间复杂度:O(rows*cols)。 递归的深度最大可能是整个网格的大小,因此最大可能使用 其中 rows 是给定网格中的行数,cols 是列数。我们访问每个网格最多一次
dfs c++
class Solution {
public:
vector<vector<int>> directions ={{0,1},{1,0},{0,-1},{-1,0}}; //顺时针
vector<vector<bool>> visited; //不修改grid
int rows;
int cols;
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int res =0 ;//最大岛屿的面积
rows =grid.size();
cols =grid[0].size();
visited.resize(rows,vector<bool>(cols,false));
for(int i =0 ;i<rows;i++)
{
for(int j=0;j<cols;j++)
{
if ( false == visited[i][j] )
{
res =max(res,dfs(grid,i,j));
}
}
}
return res;
}
//遍历 返回面积
int dfs(vector<vector<int>>& grid,int i,int j)
{
//约束条件1 边界
if ( i < 0 || i >= rows || j < 0 || j >= cols )
{
return 0;//面积为 0
}
//约束条件2 //防止环
if (visited[i][j] == true)
{
return 0; //已经计算过一次。
}
visited[i][j] = true;
//约束条件2 //防止环
if (grid[i][j] == 0)
{
return 0; //面积为 0
}
//计算岛屿面积
int area = 1;//单元格为1
for (int index = 0; index < 4; index++){
area+=dfs(grid,i+directions[index][0],j+directions[index][1]);
}
return area;
}
};
思路:
深度优先遍历,岛屿的面积是累加的,总和为以当前节点为根的树的所有节点
复杂度分析:
代码(C++):
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
int res = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j])
res = max(res, dfs(grid, i, j));
}
}
return res;
}
private:
int dfs(vector<vector<int>>& grid, int y, int x) {
if (x < 0 || x >= grid[0].size() || y < 0 || y >= grid.size() || grid[y][x] == 0) return 0;
int cnt = 1;
grid[y][x] = 0;
cnt += dfs(grid, y + 1, x);
cnt += dfs(grid, y, x + 1);
cnt += dfs(grid, y - 1, x);
cnt += dfs(grid, y, x - 1);
return cnt;
}
};
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int ans = 0;
for (int i = 0; i != grid.size(); ++i) {
for (int j = 0; j != grid[0].size(); ++j) {
int cur = 0;
stack<int> stacki;
stack<int> stackj;
stacki.push(i);
stackj.push(j);
while (!stacki.empty()) {
int cur_i = stacki.top(), cur_j = stackj.top();
stacki.pop();
stackj.pop();
if (cur_i < 0 || cur_j < 0 || cur_i == grid.size() || cur_j == grid[0].size() || grid[cur_i][cur_j] != 1) {
continue;
}
++cur;
grid[cur_i][cur_j] = 0;
int di[4] = {0, 0, 1, -1};
int dj[4] = {1, -1, 0, 0};
for (int index = 0; index != 4; ++index) {
int next_i = cur_i + di[index], next_j = cur_j + dj[index];
stacki.push(next_i);
stackj.push(next_j);
}
}
ans = max(ans, cur);
}
}
return ans;
}
};
Java Code:
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int res = 0;
for(int i = 0; i < grid.length; i++){
for(int j = 0; j < grid[0].length; j++){
if(grid[i][j] == 1){
res = Math.max(res, dfs(grid, i, j));
}
}
}
return res;
}
public int dfs(int[][] grid, int i, int j){
if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0){
return 0;
}
grid[i][j] = 0;
return 1 + dfs(grid, i - 1, j) + dfs(grid, i + 1, j) + dfs(grid, i, j - 1) + dfs(grid, i, j + 1);
}
}
复杂度分析
令 n 为数组长度。
class Solution {
public int maxAreaOfIsland(int[][] grid) {
// 最大面积
int res = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
// 如果是岛屿 那么遍历他的四周
if (grid[i][j] == 1) {
res = Math.max(res, dfs(i, j, grid));
}
}
}
return res;
}
// 每次调用的时候默认num为1,进入后判断如果不是岛屿,则直接返回0,就可以避免预防错误的情况。
// 每次找到岛屿,则直接把找到的岛屿改成0,这是传说中的沉岛思想,就是遇到岛屿就把他和周围的全部沉默。
private int dfs(int i, int j, int[][] grid) {
if (i < 0 || j < 0 || i >= grid.length || j >= grid[i].length || grid[i][j] == 0) {
return 0;
}
grid[i][j] = 0;
int num = 1;
num += dfs(i + 1, j, grid);
num += dfs(i - 1, j, grid);
num += dfs(i, j + 1, grid);
num += dfs(i, j - 1, grid);
return num;
}
}
类似题目: 200. 岛屿数量 https://leetcode-cn.com/problems/number-of-islands/
BFS
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
DIRS = [(0,1), (1,0), (-1,0), (0,-1)]
def bfs(i, j):
grid[i][j] = 0
deque = collections.deque([(i, j)])
while deque:
i, j = deque.popleft()
for dx,dy in DIRS:
x,y = i+dx,j+dy
if 0<=x<m and 0<=y<n and grid[x][y]==1:
grid[x][y] = 0 # 保证每个位置仅被访问一次
deque.append((x,y))
cnt = 0
m,n = len(grid), len(grid[0])
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
bfs(i, j)
cnt += 1
return cnt
复杂度分析
思路 BFS class Solution { public int maxAreaOfIsland(int[][] grid) { int max = 0; for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[0].length; j++) { max = Math.max(max, getIslandArea(i, j, grid)); } return max; }
private int getIslandArea(int i, int j, int[][] grid) { if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0) { return 0; } grid[i][j] = 0; return 1 + getIslandArea(i - 1, j, grid) + getIslandArea(i + 1, j, grid) + getIslandArea(i, j - 1, grid)
} 时间复杂度:O(mn) 空间复杂度:O(mn)
func maxAreaOfIsland(grid [][]int) int { res := 0.0
for i := 0; i < len(grid); i++ {
for j := 0; j < len(grid[i]); j++ {
if grid[i][j] == 1 {
res = math.Max(float64(res), float64(dfs(i, j, grid)))
}
}
}
return int(res)
}
func dfs(i int, j int, grid [][]int) (num int) { // 越界时直接返回0 if i < 0 || j < 0 || i >= len(grid) || j >= len(grid[i]) || grid[i][j] == 0 { return 0 }
// 将找到的岛屿改成0
grid[i][j] = 0
num = 1
// 右
num += dfs(i+1, j, grid)
// 左
num += dfs(i-1, j, grid)
// 上
num += dfs(i, j+1, grid)
// 下
num += dfs(i, j-1, grid)
return num
}
class Solution: def numIslands(self, grid: List[List[str]]) -> int: n = len(grid) m = len(grid[0]) def dfs(i,j): if -1<i<n and -1<j<m and grid[i][j] == '1': grid[i][j] = 0 dfs(i-1,j) dfs(i+1,j) dfs(i,j-1) dfs(i,j+1) return 0
ans = 0
for i in range(n):
for j in range(m):
if grid[i][j] == '1':
dfs(i,j)
ans += 1
return ans
public int maxAreaOfIsland(int[][] grid) {
int max = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
max = Math.max(max, helper(grid, i, j));
}
}
}
return max;
}
public int helper(int[][] grid, int i, int j) {
if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0) {
return 0;
}
grid[i][j] = 0;
return 1 + helper(grid, i - 1, j) + helper(grid, i + 1, j) + helper(grid, i, j - 1) + helper(grid, i, j + 1);
}
class Solution:
def maxAreaOfIsland(self, grid):
rows, cols = len(grid), len(grid[0])
def dfs(row, col):
if not grid[row][col]:
return 0
grid[row][col] = 0
count = 1
for i, j in [(1, 0), (- 1, 0), (0, 1), (0, - 1)]:
if row + i >= 0 and row + i < rows and col + j >=0 and col + j < cols:
count += dfs(row + i, col + j)
return count
ans = 0
for row in range(rows):
for col in range(cols):
if grid[row][col] == 1:
ans = max(ans, dfs(row, col))
return ans
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int res = 0;
for(int i = 0; i < grid.length; i++){
for(int j = 0; j < grid[0].length; j++){
if(grid[i][j] == 1){
res = Math.max(res, dfs(grid, i, j));
}
}
}
return res;
}
public int dfs(int[][] grid, int i, int j){
if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0){
return 0;
}
grid[i][j] = 0;
return 1 + dfs(grid, i - 1, j) + dfs(grid, i + 1, j) + dfs(grid, i, j - 1) + dfs(grid, i, j + 1);
}
}
null
入选理由
暂无
题目地址
null
前置知识
暂无
题目描述