LeetCode 695.岛屿的最大面积、200. 岛屿的个数、130. 被围绕的区域(递归求解)

岛屿的最大面积

题目
在这里插入图片描述
DFS(深度优先搜索):假设刚开始所有节点都是没有访问过的,从某一节点出发,先标记它为已访问,然后以它为中心向四周去寻找新的没有访问过的节点,以此类推,直到所有点都被访问完。
解题思路:采用递归的思想,遍历每一个为1的节点。把当前节点标为0,从它出发访问周围为1的节点,以此类推。递归的方法需要有返回值,每访问一个节点,返回值累加1,最终初始调用处会得到一个“岛屿的面积”,不断更新最大值,最后得到一个最大岛屿面积并返回。
更新参数的式子:result=Math.max(result,find(grid, i, j));一个式子可以实现比较和赋值,相比以往的if和else的形式,这样会简便很多。
出界的判断

if(i<0||j<0||i>=grid.length||j>=grid[0].length||grid[i][j]==0){
    	return 0;
}

代码

class Solution {
    public int maxAreaOfIsland(int[][] grid) {
    	int result=0;
    	for(int i=0;i<grid.length;i++){
    		for(int j=0;j<grid[0].length;j++){
    			result=Math.max(result,find(grid, i, j));
    		}
    	}
    	return result;
    }        
    public int find(int[][] grid,int i,int j){
    	if(i<0||j<0||i>=grid.length||j>=grid[0].length||grid[i][j]==0){
    		return 0;
    	}else{
    		grid[i][j]=0;
    		return 1+find(grid, i-1, j)+find(grid, i, j-1)+find(grid, i+1, j)+find(grid, i, j+1);
    	}    	    	
    }    
}

岛屿的个数

题目
在这里插入图片描述
分析:依然可以当做一道dfs题通过递归来解决。解题思路是每次发现一个1就计数加一,就从它出发遍历相连的1,把所有访问到的1置0,这样可以避免重复计数。最后就能得到到一个岛屿数。
代码

public class Solution {
    public int numIslands(char[][] grid) {
    	if(grid==null){
    		return 0;
    	}
    	int count=0;
        for(int i=0;i<grid.length;i++){
        	for(int j=0;j<grid[0].length;j++){
        		if(grid[i][j]=='1'){
        			count++;
        			find(grid, i, j);
        		}
        	}
        }
        return count;
    }
    public void find(char[][] grid,int i,int j){
    	   if(i<0||j<0||i>=grid.length||j>=grid[0].length||grid[i][j]=='0'){
    		   return;
    	   }else {
    		   grid[i][j]='0';
    		   find(grid, i+1, j);
    		   find(grid, i-1, j);
    		   find(grid, i, j+1);
    		   find(grid, i, j-1);
    	   }
    } 
}

被围绕的区域

题目
在这里插入图片描述
分析:这题思路可以更加活一点,依然使用深度优先搜索的思想。题目的意思就是把被包围的O改为X,那么只要对边界的O和被包围的O做出区分就可以了。我的思路是先实例化一个数组,遍历每一个周边的O,以它们为中心开始遍历,把所有与边界O关联的O所在位置都在这个自定义的数组中标记为1。最后遍历一遍原始数组,把所有相应位置没有被标记的O修改为X。
特殊情况处理

    	if(board==null||board.length<3||board[0].length<3){
    		return ;
    	} 

完整代码

class Solution {	
    public void solve(char[][] board) {
    	if(board==null||board.length<3||board[0].length<3){
    		return ;
    	}    	   
        int[][] sort=new int[board.length][board[0].length];
        for(int i=0;i<board.length;i++){
        	for(int j=0;j<board[0].length;j++){
        		if((i==0||i==board.length-1||j==0||j==board[0].length-1)){
        			find(board, sort, i, j);
        		}
        	}
        }
        for(int i=0;i<board.length;i++){
        	for(int j=0;j<board[0].length;j++){
        		if(board[i][j]=='O'&&sort[i][j]==0){
        			board[i][j]='X';
        		}
        	}
        }
    }    
    public void find(char[][] board,int[][] sort,int i,int j){
    	if(i<0||j<0||i>=board.length||j>=board[0].length){
    		return;
    	}else if(board[i][j]=='O'&&sort[i][j]==0){
    		sort[i][j]=1;
    		find(board, sort, i+1, j);
    		find(board, sort, i-1, j);
    		find(board, sort, i, j+1);
    		find(board, sort, i, j-1);
    	}
    }                
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值