【经典LeetCode算法题目专栏分类】【第9期】深度优先搜索DFS与并查集:括号生成、岛屿问题、扫雷游戏

简介: 【经典LeetCode算法题目专栏分类】【第9期】深度优先搜索DFS与并查集:括号生成、岛屿问题、扫雷游戏

DFS

括号生成

DFS
class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        def DFS(left, right, s):
            if left == n and right == n:
                res.append(s)
                return
            if left < n:
                DFS(left+1,right,s+'(')
            if right < left:
                DFS(left,right + 1,s+')')
        res = []
        DFS(0,0,'')
        return res
BFS
class Node:
    def __init__(self, left, right, s):
        self.left = left
        self.right = right
        self.s = s
class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        # BFS写法
        res = []
        if n == 0:
            return res
        queue = [Node(n,n,'')]
        while queue:
            node = queue.pop(0)
            if node.left == 0 and node.right == 0:
                res.append(node.s)
            if node.left > 0:
                queue.append(Node(node.left-1, node.right, node.s+'('))
            if node.right > 0 and node.right > node.left:
                queue.append(Node(node.left, node.right-1, node.s+')'))
        return res
# 写法2:
class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        # BFS写法
        res = []
        if n == 0:
            return res
        queue = [(n,n,'')]
        while queue:
            node = queue.pop(0)
            if node[0] == 0 and node[1] == 0:
                res.append(node[2])
            if node[0] > 0:
                queue.append((node[0]-1, node[1], node[2]+'('))
            if node[1] > 0 and node[1] > node[0]:
                queue.append((node[0], node[1]-1, node[2]+')'))
        return res

通常搜索几乎都是用深度优先遍历(回溯算法)。

广度优先遍历,得自己编写结点类,显示使用队列这个数据结构。深度优先遍历的时候,就可以直接使用系统栈,在递归方法执行完成的时候,系统栈顶就把我们所需要的状态信息直接弹出,而无须编写结点类和显示使用栈。

将BFS写法中的pop(0)改为pop()即为深度优先的迭代形式。

对比迭代的BFS写法与递归的DFS写法,可以看到,BFS其实是将DFS的参数当做队列中的一个元素来进行处理罢了,其他的与DFS没有什么区别。

并查集

岛屿问题

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        self.m = len(grid)
        self.n = len(grid[0])
        res = 0
        for i in range(self.m):
            for j in range(self.n):
                if grid[i][j] == '1':
                    self.sink(i,j,grid)
                    res += 1
        return res
    
    def sink(self, i, j, grid):
        grid[i][j] = '0'
        for ni,nj in [(i-1,j),(i+1,j),(i,j-1),(i,j+1)]:
            if 0<=ni<self.m and 0<=nj<self.n and grid[ni][nj] == '1':
                self.sink(ni,nj,grid)

扫雷游戏

# DFS
class Solution:
    def updateBoard(self, board: List[List[str]], click: List[int]) -> List[List[str]]:
        # DFS
        i, j = click
        row, col = len(board), len(board[0])
        if board[i][j] == "M":
            board[i][j] = "X"
            return board
        # 计算空白快周围的雷数量
        def cal(i, j):
            res = 0
            for x in [1, -1, 0]:
                for y in [1, -1, 0]:
                    if x == 0 and y == 0: continue
                    if 0 <= i + x < row and 0 <= j + y < col and board[i + x][j + y] == "M": res += 1
            return res
        def dfs(i, j):
            num = cal(i, j)
            if num > 0:
                board[i][j] = str(num)
                return
            board[i][j] = "B"
            for x in [1, -1, 0]:
                for y in [1, -1, 0]:
                    if x == 0 and y == 0: continue
                    nxt_i, nxt_j = i + x, j + y
                    if 0 <= nxt_i < row and 0 <= nxt_j < col and board[nxt_i][nxt_j] == "E": dfs(nxt_i, nxt_j)
        dfs(i, j)
        return board
# BFS
class Solution:
    def updateBoard(self, board: List[List[str]], click: List[int]) -> List[List[str]]:
        i, j = click
        row, col = len(board), len(board[0])
        if board[i][j] == "M":
            board[i][j] = "X"
            return board
        # 计算空白块周围的雷数目
        def cal(i, j):
            res = 0
            for x in [1, -1, 0]:
                for y in [1, -1, 0]:
                    if x == 0 and y == 0: continue
                    if 0 <= i + x < row and 0 <= j + y < col and board[i + x][j + y] == "M": res += 1
            return res
        def bfs(i, j):
            queue = [(i,j)]
            while queue:
                i, j = queue.pop(0)
                num = cal(i, j)
                if num > 0:
                    board[i][j] = str(num)
                    continue
                board[i][j] = "B"
                for x in [1, -1, 0]:
                    for y in [1, -1, 0]:
                        if x == 0 and y == 0: continue
                        nxt_i, nxt_j = i + x, j + y
                        if nxt_i < 0 or nxt_i >= row or nxt_j < 0 or nxt_j >= col: continue
                        if board[nxt_i][nxt_j] == "E":
                            queue.append((nxt_i, nxt_j))
                            board[nxt_i][nxt_j] = "B"  # 主要是用于标识该点已经被访问过,防止后续重复的添加相同的‘E’点
        bfs(i, j)
        return board


相关文章
|
2月前
|
算法
Leetcode第45题(跳跃游戏II)
这篇博客文章讨论了如何使用贪心算法解决LeetCode第45题“跳跃游戏II”,目的是找到使用最少跳跃次数到达数组末尾的策略。
79 8
Leetcode第45题(跳跃游戏II)
|
2月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
40 0
|
4月前
|
算法 搜索推荐
LeetCode第75题颜色分类
文章介绍了LeetCode第75题"颜色分类"的解法,通过双指针技术对数组中的0、1和2进行排序,避免了传统的排序算法,提供了一种时间复杂度为O(n)的高效解决方案。
LeetCode第75题颜色分类
|
4月前
|
算法
LeetCode第55题跳跃游戏
LeetCode第55题"跳跃游戏"的解题方法,通过记录当前最远可达到的位置并判断每个位置是否可达以及能否到达末尾,有效解决了跳跃至数组末尾的可行性问题。
LeetCode第55题跳跃游戏
|
21天前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
2月前
Leetcode第55题(跳跃游戏)
LeetCode第55题“跳跃游戏”要求判断在一个非负整数数组中,从第一个位置出发,是否能够到达最后一个位置,其中每个位置的元素代表可跳跃的最大长度。
31 0
|
2月前
|
人工智能 算法 Java
【搜索算法】数字游戏(C/C++)
【搜索算法】数字游戏(C/C++)
|
4月前
|
算法
测试工程师的技能升级:LeetCode算法挑战与职业成长
这篇文章通过作者亲身体验LeetCode算法题的过程,探讨了测试工程师学习算法的重要性,并强调了算法技能对于测试职业成长的必要性。
70 1
测试工程师的技能升级:LeetCode算法挑战与职业成长
|
4月前
|
算法
LeetCode第45题跳跃游戏 II
LeetCode第45题"跳跃游戏 II"的解题方法,通过一次循环和选择每个位置的最大可跳距离,有效减少了跳跃次数,简化了问题。
|
4月前
|
算法
互动游戏解决遇到问题之基于射线投射寻路算法的问题如何解决
互动游戏解决遇到问题之基于射线投射寻路算法的问题如何解决