【队列 & 栈】(四) 栈和深度优先搜索

目录

一、栈和深度优先搜索

二、栈和 DFS

三、DFS - 模板 I

三、岛屿数量

3.1 题目要求

3.2 解决过程

四、克隆图

4.1 题目要求

4.2 解决过程

五、目标和

5.1 题目要求

5.2 解决过程

六、DFS - 模板 II

七、二叉树的中序遍历

7.1 题目要求

7.2 解决过程


一、栈和深度优先搜索

树的遍历https://blog.csdn.net/qq_39478403/article/details/107329233

参考文献:https://leetcode-cn.com/leetbook/read/queue-stack/k3beh/ 


二、栈和 DFS

     

     

 

参考文献:https://leetcode-cn.com/leetbook/read/queue-stack/gro21/


三、DFS - 模板 I

     

     

// Java
/*
 * Return true if there is a path from cur to target.
 */
boolean DFS(Node cur, Node target, Set<Node> visited) {
    return true if cur is target;
    for (next : each neighbor of cur) {
        if (next is not in visited) {
            add next to visted;
            return true if DFS(next, target, visited) == true;
        }
    }
    return false;
}

     

     

参考文献:https://leetcode-cn.com/leetbook/read/queue-stack/gp5a7/ 


三、岛屿数量

3.1 题目要求

3.2 解决过程

法一BFS 迭代实现。沿竖直和水平方向遍历输入矩阵,每发现一个陆地 (标号1),就对其进行 BFS,并将可由 BFS 访问/搜索到的陆地都置为已访问/已搜索 (标号0) 以表示属于同一个岛屿,且因为已访问/已搜索而不必在后续过程中再次访问/搜索 (意为不会访问同一个节点两次)。空间复杂度 O(n),时间复杂度 O(n)。

2020/09/02 - 70.26% (80ms)

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        land_nums = 0  # 岛屿数量
        for row in range(len(grid)):  # 遍历行
            for col in range(len(grid[0])):  # 遍历列
                if grid[row][col] == '1':  # 发现陆地
                    land_nums += 1  # 岛屿数量 +1
                    grid[row][col] = '0'  # 将已访问/已探索的陆地置为 0, 以后便不必再重复访问/搜索
                    # 对已发现陆地通过 BFS 扩张/辐射, 将与之相邻的陆地都标记为已访问/已探索状态
                    land_positions = collections.deque()  # 内置双端队列, 保存已访问/已探索相邻陆地坐标
                    land_positions.append([row, col])  # 当前已访问/已探索陆地坐标入队
                    while len(land_positions) > 0:  # 只要当前队列中还保存有已访问/已探索陆地坐标
                        x, y = land_positions.popleft()  # 出队探索
                        for new_x, new_y in [[x, y+1], [x, y-1], [x+1, y], [x-1, y]]:  # 向 4 个方向扩张/辐射
                            # 判断有效性, 要求是坐标界限范围内的陆地
                            if (0 <= new_x < len(grid)) and (0 <= new_y < len(grid[0])) and (grid[new_x][new_y] == '1'):
                                grid[new_x][new_y] = '0'  # 因为可由 BFS 访问到, 故属同一块岛,将其置 0 代表已访问/已探索
                                land_positions.append([new_x, new_y])  # 已访问/已探索陆地坐标入队
        return land_nums

法一改:BFS 迭代实现 - 函数封装空间复杂度 O(n),时间复杂度 O(n)。

2020/09/02 - 70.26% (80ms)

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        from collections import deque  # 双端队列
        if not grid: 
            return 0
        row = len(grid)  # 行数
        col = len(grid[0])  # 列数
        cnt = 0  # 岛屿数

        def bfs(i, j):
            queue = deque()  # 保存已访问/已探索的陆地队列
            grid[i][j] = "0"  # 将已发现的陆地置为已访问/已探索状态 0 
            queue.appendleft((i, j))  # 已发现陆地坐标入队
            while queue:  # 只要队列中还有坐标
                i, j = queue.pop()  # 弹出一个坐标
                for x, y in [[-1, 0], [1, 0], [0, -1], [0, 1]]:  # 向周围 4 个方向以单位距离搜索
                    tmp_i = i + x
                    tmp_j = j + y
                    # 若在范围内发现新陆地
                    if (0 <= tmp_i < row) and (0 <= tmp_j < col) and (grid[tmp_i][tmp_j] == "1"):
                        grid[tmp_i][tmp_j] = "0"  # 将已发现的陆地置为已访问/已探索状态 0 
          
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值