【力扣hot100】刷题笔记Day11

前言

  • 科研不顺啊......又不想搞了,随便弄弄吧,多花点时间刷题,今天开启二叉树!

94. 二叉树的中序遍历 - 力扣(LeetCode)

递归

```python
# 最简单递归
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)
        # 前/后序就换一下顺序

# 通用模板        
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res = []  # 收集结果
        def dfs(root):
            if not root:  # 访问到空结点直接返回
                return
            # 前后序就以下换成对应顺序
            dfs(root.left)        # 左
            res.append(root.val)  # 中
            dfs(root.right)       # 右
        dfs(root)
        return res
```

迭代

```python
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        stack = []
        while stack or root:
            # 不断往左子树方向走,每走一次就将当前节点保存到栈中
			# 这是模拟递归的调用
            while root:
                # res.append(root.val)  # 前/后序改到这
                stack.append(root)
                root = root.left  # 后序改成right
            # 当前节点为空,说明左边走到头了,从栈中弹出节点并保存
			# 然后转向右边节点,继续上面整个过程
            temp = stack.pop()
            res.append(temp.val)  # 前/后序删掉
            root = temp.right  # 后序改成left
        return res  # 后序的话就是[中右左]反过来,return res[::-1]
```

Morris遍历

  • 过程看官解的动图
  • cur无左孩子,说明到最左端:
    • 加入结果,cur右移
  • cur有左孩子,说明有前驱,找前驱
    • 前驱无右孩:生成链接、cur左移
    • 前驱有右孩:断开连接,记录cur结果,cur右移
```python
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        res = []
        cur, prev = root, None
        while cur:
            if not cur.left:  # 无左孩,到最左端
                res.append(cur.val)  # 将当前节点cur的值加入结果列表
                cur = cur.right  # 将当前节点指向右子树
            else:
                prev = cur.left  # 找到当前节点cur的左子树的最右节点(前驱)
                while prev.right and prev.right != cur:
                    prev = prev.right
                if not prev.right:  # 前驱无右孩
                    prev.right = cur  # 添加连接
                    # res.append(cur.val)  # 如果是前序,下面的加入结果改到这
                    cur = cur.left  # 左移
                else:  # 前驱有右孩
                    prev.right = None  # 断开连接
                    res.append(cur.val)  # 将当前节点cur的值加入结果列表
                    cur = cur.right  # 右移
        return res
```

标记迭代

```python
class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        stack = [(0, root)]  # 0表示当前未访问,1表示已访问
        while stack:
            flag, cur = stack.pop()
            if not cur: continue
            if flag == 0:
                stack.append((0, cur.right))  # 右
                stack.append((1, cur))        # 中
                stack.append((0, cur.left))   # 左
            else:
                res.append(cur.val)
        return res
```

二叉树所有遍历模板总结

144. 二叉树的前序遍历 - 力扣(LeetCode)

145. 二叉树的后序遍历 - 力扣(LeetCode)

102. 二叉树的层序遍历 - 力扣(LeetCode)

两个列表

```python
class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root:
            return []
        cur, res = [root], []  # cur表示当前层未访问结点,res为结果
        while cur:
            lay, layval = [], []  # lay表示下一层该访问结点,layval表示当前层的数值列表
            for node in cur:  # 遍历当前层所有结点
                layval.append(node.val)
                if node.left: lay.append(node.left)     # 添加左结点到下一层
                if node.right: lay.append(node.right)   # 添加右结点到下一层
            cur = lay  # 更新下一层
            res.append(layval)  # 更新结果集
        return res
```

队列BFS

```python
"""
# BFS模板
while queue 不空:
    cur = queue.pop()
    for 节点 in cur的所有相邻节点:
        if 该节点有效且未访问过:
            queue.push(该节点)
"""
class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root:
            return []
        res = []  # 结果
        q = deque()  # 队列
        q.append(root)
        # q = deque([root])  # 直接赋值需要传入可迭代对象[]
        while q:
            vals = []  # 存当前层的值
            for i in range(len(q)):  # 遍历队列中(当前层)所有结点
                cur = q.popleft()
                vals.append(cur.val)
                if cur.left: q.append(cur.left)
                if cur.right: q.append(cur.right)
            res.append(vals)
        return res
```

DFS递归

```python
class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        res = []
        self.level(root, 0, res)
        return res

    def level(self, root: Optional[TreeNode], level: int, res: List[List[int]]):
        if not root: return
        if len(res) == level: res.append([])  # 一直向左遍历,新增层数对应的结果列表
        res[level].append(root.val)  # 当前结点加入当前层的结果里去
        if root.left: self.level(root.left, level+1, res)   # 递归遍历左子树
        if root.right: self.level(root.right, level+1, res) # 递归遍历右子树
```

589. N 叉树的前序遍历 - 力扣(LeetCode)

递归

```python
# 简单递归
class Solution:
    def preorder(self, root: 'Node') -> List[int]:
        if not root: return
        temp = []
        for child in root.children:
            temp += self.preorder(child)
        return [root.val] + temp
# 常规递归
class Solution:
    def preorder(self, root: 'Node') -> List[int]:
        res = []
        def dfs(cur):
            if not cur: return
            res.append(cur.val)
            for child in cur.children:  # 遍历每一个子结点
                dfs(child)
        dfs(root)
        return res
```

迭代

```python
class Solution:
    def preorder(self, root: 'Node') -> List[int]:
        if not root: return
        res = []
        s = [root]
        while s:
            cur = s.pop()
            res.append(cur.val)
            for child in cur.children[::-1]:  # 从右往左添加进栈
                s.append(child)
            # s.extend(cur.children[::-1])  # 也可以直接拼接
        return res
```

590. N 叉树的后序遍历 - 力扣(LeetCode)

后言

  • 今天把以上几个二叉树遍历的题目模板刷熟!这样后面的题才能信手拈来~
相关推荐
hsling松子10 分钟前
使用PaddleHub智能生成,献上浓情国庆福
人工智能·算法·机器学习·语言模型·paddlepaddle
belldeep14 分钟前
python:reportlab 将多个图片合并成一个PDF文件
python·pdf·reportlab
dengqingrui12335 分钟前
【树形DP】AT_dp_p Independent Set 题解
c++·学习·算法·深度优先·图论·dp
C++忠实粉丝37 分钟前
前缀和(8)_矩阵区域和
数据结构·c++·线性代数·算法·矩阵
ZZZ_O^O1 小时前
二分查找算法——寻找旋转排序数组中的最小值&点名
数据结构·c++·学习·算法·二叉树
CV-King2 小时前
opencv实战项目(三十):使用傅里叶变换进行图像边缘检测
人工智能·opencv·算法·计算机视觉
代码雕刻家2 小时前
数据结构-3.9.栈在递归中的应用
c语言·数据结构·算法
雨中rain2 小时前
算法 | 位运算(哈希思想)
算法
FreakStudio3 小时前
全网最适合入门的面向对象编程教程:56 Python字符串与序列化-正则表达式和re模块应用
python·单片机·嵌入式·面向对象·电子diy
丶21363 小时前
【CUDA】【PyTorch】安装 PyTorch 与 CUDA 11.7 的详细步骤
人工智能·pytorch·python