class Solution {
int[] dx = {1,0,0,-1};
int[] dy = {0,1,-1,0};
public int[][] floodFill(int[][] image, int sr, int sc, int color) {
int currentColor = image[sr][sc];
if(currentColor != color) {
dfs(image,sr,sc,currentColor,color);
}
return image;
}
public void dfs(int[][] image,int x,int y,int currentColor,int color) {
if(image[x][y] == currentColor) {
image[x][y] = color;
for(int i=0;i<4;i++) {
int mx = x + dx[i];
int my = y + dy[i];
if(mx >= 0 && mx < image.length && my >= 0 && my < image[0].length) {
dfs(image,mx,my,currentColor,color);
}
}
}
}
}
在这里插入代码片
class Solution {
int[] dx = {1,0,0,-1};
int[] dy = {0,1,-1,0};
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++) {
res = Math.max(res,dfs(grid,i,j));
}
}
return res;
}
private int dfs(int[][] grid,int x,int y) {
if(x < 0 || y < 0 || x >= grid.length || y >= grid[0].length || grid[x][y] == 0) {
return 0;
}
int num = 1;
grid[x][y] = 0;
for(int i=0;i<4;i++) {
int mx = x + dx[i];
int my = y + dy[i];
if(mx >= 0 && mx < grid.length && my >= 0 && my < grid[0].length) {
num += dfs(grid,mx,my);
}
}
return num;
}
}
class Solution {
int[] dx = {1,0,0,-1};
int[] dy = {0,1,-1,0};
public int numIslands(char[][] grid) {
int m = grid.length;
int n = grid[0].length;
int num_islands = 0;
for(int i=0;i<m;i++) {
for(int j=0;j<n;j++) {
if(grid[i][j] == '1') {
num_islands++;
dfs(grid,i,j);
}
}
}
return num_islands;
}
public void dfs(char[][] grid,int x,int y) {
if(x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] == '0') {
return;
}
grid[x][y] = '0';
for(int i=0;i<4;i++) {
int mx = x + dx[i];
int my = y + dy[i];
if(mx >= 0 && mx < grid.length && my >= 0 && my < grid[0].length && grid[mx][my] != '0') {
dfs(grid,mx,my);
}
}
}
}
该道题与第200题岛屿数目十分相似,唯一不同的就是边界的处理,在该道题中,边界的陆地并不能被称为封闭岛屿,所以首先先对边界的行和列进行处理。
DFS解法
class Solution {
int[] dx = {-1,0,0,1};
int[] dy = {0,-1,1,0};
public int closedIsland(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
//先从边界开始对陆地进行DFS搜索并将陆地标记为2
//先对第一列和最后一列进行DFS
for(int i=0;i<m;i++) {
dfs(grid,i,0);
dfs(grid,i,n-1);
}
//再对第一行和最后一行进行DFS搜索并将陆地标记为2
for(int j=0;j<n;j++) {
dfs(grid,0,j);
dfs(grid,m-1,j);
}
int res = 0;
for(int i=0;i<m;i++) {
for(int j=0;j<n;j++) {
if(grid[i][j] == 0) {
res++;
dfs(grid,i,j);
}
}
}
return res;
}
public void dfs(int[][] grid,int x,int y) {
if(x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] == 1 || grid[x][y] == 2) {
return;
}
grid[x][y] = 2;
for(int i=0;i<4;i++) {
int mx = x + dx[i];
int my = y + dy[i];
dfs(grid,mx,my);
}
}
}
这道题与上面的那道题也有相似之处,首先先使用一次DFS算法,将不符合条件的陆地改为水域,然后再使用一次和上面相同的DFS算法对grid2中的陆地进行统计。
class Solution {
int[] dx = {-1,0,0,1};
int[] dy = {0,-1,1,0};
public int countSubIslands(int[][] grid1, int[][] grid2) {
int m = grid2.length;
int n = grid2[0].length;
for(int i=0;i<m;i++) {
for(int j=0;j<n;j++) {
if(grid2[i][j] == 1 && grid1[i][j] != 1) {
dfs(grid2,i,j);
}
}
}
int res = 0;
for(int i=0;i<m;i++) {
for(int j=0;j<n;j++) {
if(grid2[i][j] == 1) {
res++;
dfs(grid2,i,j);
}
}
}
return res;
}
public void dfs(int[][] grid2,int x,int y) {
if(x < 0 || x >= grid2.length || y < 0 || y >= grid2[0].length || grid2[x][y] == 0) {
return;
}
grid2[x][y] = 0;
for(int i=0;i<4;i++) {
int mx = x + dx[i];
int my = y + dy[i];
dfs(grid2,mx,my);
}
}
}
class Solution {
int[] dx = {-1,0,0,1};
int[] dy = {0,-1,1,0};
public void solve(char[][] board) {
int m = board.length;
int n = board[0].length;
//首先先对第一列和最后一列进行dfs
for(int i=0;i<m;i++) {
if(board[i][0] == 'O') {
dfs(board,i,0);
}
if(board[i][n-1] == 'O') {
dfs(board,i,n-1);
}
}
//其次对第一行和最后一行进行dfs
for(int j=0;j<n;j++) {
if(board[0][j] == 'O') {
dfs(board,0,j);
}
if(board[m-1][j] == 'O') {
dfs(board,m-1,j);
}
}
for(int i=0;i<m;i++) {
for(int j=0;j<n;j++) {
if(board[i][j] == 'F') {
board[i][j] = 'O';
}else if(board[i][j] == 'O') {
board[i][j] = 'X';
}
}
}
}
public void dfs(char[][] board,int x,int y) {
if(x < 0 || x >= board.length || y < 0 || y >= board[0].length || board[x][y] != 'O') {
return;
}
board[x][y] = 'F';
for(int i=0;i<4;i++) {
int mx = x + dx[i];
int my = y + dy[i];
dfs(board,mx,my);
}
}
}
class Solution {
int[] dx = {-1,0,0,1};
int[] dy = {0,1,-1,0};
public int islandPerimeter(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int res = 0;
for(int i=0;i<m;i++) {
for(int j=0;j<n;j++) {
if(grid[i][j] == 1) {
res += dfs(grid,i,j);
}
}
}
return res;
}
public int dfs(int[][] grid,int x,int y) {
if(x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] == 0) {
return 1;
}
if(grid[x][y] == 2) {
return 0;
}
grid[x][y] = 2;
int res = 0;
for(int i=0;i<4;i++) {
int mx = x + dx[i];
int my = y + dy[i];
res += dfs(grid,mx,my);
}
return res;
}
}
class Solution {
int[] dx = {-1,0,0,1};
int[] dy = {0,-1,1,0};
public List<List<Integer>> pacificAtlantic(int[][] heights) {
int m = heights.length;
int n = heights[0].length;
//定义访问数组
boolean[][] po = new boolean[m][n];
boolean[][] ao = new boolean[m][n];
//首先先对第一列和最后一列进行dfs
for(int i=0;i<m;i++) {
dfs(heights,i,0,po,heights[i][0]);
dfs(heights,i,n-1,ao,heights[i][n-1]);
}
//其次对第一行和最后一行进行dfs
for(int j=0;j<n;j++) {
dfs(heights,0,j,po,heights[0][j]);
dfs(heights,m-1,j,ao,heights[m-1][j]);
}
List<List<Integer>> res = new ArrayList<>();
//最后对其进行取交集
for(int i=0;i<m;i++) {
for(int j=0;j<n;j++) {
if(po[i][j] == true && ao[i][j] == true) {
res.add(Arrays.asList(i,j));
}
}
}
return res;
}
public void dfs(int[][] heights,int x,int y,boolean[][] visit,int pre) {
int m = heights.length;
int n = heights[0].length;
if(x < 0 || x >= m || y < 0 || y >= n || visit[x][y] || pre > heights[x][y]) {
return;
}
visit[x][y] = true;
for(int i=0;i<4;i++) {
int mx = x + dx[i];
int my = y + dy[i];
dfs(heights,mx,my,visit,heights[x][y]);
}
}
}