leetcode笔记|第十二周 BFS

102 二叉树的层序遍历

给一个二叉树,返回其按 层序遍历 得到的节点值。 如,[ [3], [9,20], [15,7] ]

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        res = []
        queue = collections.deque()
        queue.append(root)
        # DFS模板如下
        while queue:
            curlayer = []
            size = len(queue)
            # 每次遍历当前层节点值,后面新添加的下一层的节点,在下一次while时才弹出
            for _ in range(size):
                cur = queue.popleft()
                if not cur:
                    continue # 不懂为什么不是break 反正break报错
                curlayer.append(cur.val)
                queue.append(cur.left)
                queue.append(cur.right)
            if curlayer:
                res.append(curlayer)
        return res

111 二叉树的最小深度

找到二叉树到叶子结点的最短路径节点数

# 哇咔咔咔 自己写的 一遍过 开心
class Solution:
    def minDepth(self, root: TreeNode) -> int:
        if not root: return 0
        queue = collections.deque()
        queue.append(root)
        res = 0
        while queue:
            res += 1
            size = len(queue)
            for _ in range(size):
                cur = queue.popleft()
                if not cur:
                    continue
                if not cur.left and not cur.right:
                    return res
                queue.append(cur.left)
                queue.append(cur.right)

127单词接龙

每次只能改变一个字母,(改变后的单词需要在wordList中才行),看最终能否从begin到endword,输出最少次数。

单向搜索和双向搜索效率差距很大,双向搜索有效地规避了无效路径

class Solution:
    def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
            # 用set,方便O(1)时间复杂度查找
            wordlistset = set(wordList)
            if len(wordlistset)==0 or endWord not in wordlistset:
               return 0
            
            # queue为每层队列,双向BFS使用左右队列
            lqueue = collections.deque()
            rqueue = collections.deque()
            # 记录访问过的节点
            lvisited = set()
            rvisited = set()

            lqueue.append(beginWord)
            rqueue.append(endWord)
            lvisited.add(beginWord)
            rvisited.add(endWord)

            res = 0
            while lqueue and rqueue:
                res += 1
                # 每次对少的队列进行BFS
                if len(lqueue)>len(rqueue):
                    lqueue, rqueue = rqueue, lqueue
                    lvisited, rvisited = rvisited, lvisited
                # 遍历每层
                for i in range(len(lqueue)):
                    cur = lqueue.popleft()
                    # 与右侧节点重合时,搜索结束
                    if cur in rvisited:
                        return res
                    # 每个节点的子节点为改变了一个字母的临时单词tmp
                    for k in range(len(beginWord)):
                        for j in range(26):
                            tmp = cur[:k]+chr(97+j)+cur[k+1:]
                            if tmp not in lvisited and tmp in wordlistset:
                                lqueue.append(tmp)
                                lvisited.add(tmp)
            return 0 # 没有会输出None

310 最小高度树

题目没看懂Orz

1306 跳跃游戏 III

输入:arr = [4,2,3,0,3,1,2], start = 5 # 从下标为5的地方开始,左/右跳当前元素步,看最终能否到元素为0的位置
输出:true
解释:
到达值为 0 的下标 3 有以下可能方案:
下标 5 -> 下标 4 -> 下标 1 -> 下标 3
下标 5 -> 下标 6 -> 下标 4 -> 下标 1 -> 下标 3

class Solution:
    def canReach(self, arr: List[int], start: int) -> bool:
        # 自己写的 也过了 开心开心开心
        queue = collections.deque()
        queue.append(start)
        visited = []
        visited.append(start)
        while queue:
            for _ in range(len(queue)):
                cur = queue.popleft()
                if arr[cur] == 0:
                    return True
                if cur+arr[cur] < len(arr) and cur+arr[cur] not in visited:
                    queue.append(cur+arr[cur])
                    visited.append(cur+arr[cur])
                if cur-arr[cur] >= 0 and cur-arr[cur] not in visited:
                    queue.append(cur-arr[cur])
                    visited.append(cur-arr[cur])
        return False

407 接雨水 II

困难?打扰了

913 猫和老鼠

困难?打扰了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值