【搜索】(DFS)1、岛屿的周长(easy)

本文探讨了深度优先搜索(DFS)的基本原理及其在检测环路中的作用。针对LeetCode 463题——岛屿的周长,阐述了如何利用DFS解决网格中岛屿周长的问题,包括避免重复搜索的策略以及处理网格边缘的技巧。
摘要由CSDN通过智能技术生成

深度优先搜索DFS和广度优先搜索BFS是两种最常见的优先搜索方法,被广泛地运用在图和树等 结构中进行搜索。

深度优先搜索(depth-first seach,DFS)在搜索到一个新的节点时,立即对该新节点进行遍历;遍历需要用先入后出的栈来实现,也可以通过与栈等价的递归来实现。
对于树结构而言,由于总是对新节点调用遍历,因此看起来是向着“深”的方向前进。

深度优先搜索也可以用来检测环路:记录每个遍历过的节点的父节点,若一个节点被再次遍历且父节点不同,则说明有环。我们也可以用之后会讲到的拓扑排序判断是否有环路,若最后存在入度不为零的点,则说明有环。
有时我们可能会需要对已经搜索过的节点进行标记,以防止在遍历时重复搜索某个节点,这种做法叫做状态记录或记忆化(memoization)

leetcode 463 岛屿的周长
在这里插入图片描述
在这里插入图片描述
参考题解

// 基本的 DFS 框架:每次搜索四个相邻方格
void dfs(int[][] grid, int r, int c) {
    dfs(grid, r - 1, c); // 上边相邻
    dfs(grid, r + 1, c); // 下边相邻
    dfs(grid, r, c - 1); // 左边相邻
    dfs(grid, r, c + 1); // 右边相邻
}

对于网格边缘的方格,上下左右并不都有邻居。一种做法是在递归调用之前判断方格的位置,例如位于左边缘,则不访问其左邻居。但这样一个一个判断写起来比较麻烦,我们可以用**“先污染后治理”的方法,先做递归调用,再在每个 DFS 函数的开头判断坐标是否合法**,不合法的直接返回。同样地,我们还需要判断该方格是否有岛屿(值是否为 1),否则也需要返回。

class Solution {
    public int islandPerimeter(int[][] grid) {
        for(int r=0;r<grid.length;r++){
            for(int c=0;c<grid[0].length;c++){
                if(grid[r][c]==1){
                //因为题中规定只有一个岛屿
                    return dfs(grid,r,c);
                }
            }
        }
        //没有岛屿就返回0
        return 0;

    }
    public int dfs(int[][] grid, int r, int c){
        //陆地在网格边界
        if(r<0 || r>=grid.length || c<0 ||c>=grid[0].length){
            return 1;
        }
        //与水域相邻则返回边长1
        if(grid[r][c]==0){
            return 1;
        }
        //遍历过的就不再遍历
        if(grid[r][c]!=1){
            return 0;
        }
        //此网格为陆地,且遍历过,赋值为2。
        grid[r][c]=2;
        //上下左右所有陆地的周长和。
        return dfs(grid,r-1,c)+dfs(grid,r,c-1)+ dfs(grid,r+1,c)+ dfs(grid,r,c+1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值