[leetcode 257]257. 二叉树的所有路径

257. 二叉树的所有路径

https://leetcode-cn.com/problems/binary-tree-paths/

难度简单416收藏分享切换为英文接收动态反馈

给定一个二叉树,返回所有从根节点到叶子节点的路径。

说明: 叶子节点是指没有子节点的节点。

示例:

输入:

   1
 /   \
2     3
 \
  5

输出: ["1->2->5", "1->3"]

解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3

解法1 先序遍历

# -*- coding: utf-8 -*-
from typing import List, Optional

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


class Solution:
    def binaryTreePaths(self, root: TreeNode) -> List[str]:
        self.result = []
        if not root:
            return self.result
        level = 0
        cur_result = []
        self._generate(root=root, level=level, cur_result=cur_result)

        return self.result

    def _generate(self, root: TreeNode, level, cur_result: List):

        cur_result.append(str(root.val))

        if root.left is None and root.right is None:
            r = self._generate_path(cur_result)
            self.result.append(r)
            return

        if root.left:
            self._generate(root.left, level + 1, cur_result)
            # reverse the current level
            cur_result.pop(-1)

        if root.right:
            self._generate(root.right, level + 1, cur_result)
            # reverse the current level
            cur_result.pop(-1)

    def _generate_path(self, result: List):
        if not result:
            return
        return "->".join(result)




def create_tree(array: List, i: int, n: int) -> Optional[TreeNode]:
    """
    :param array: 完全二叉树 对应的数组
    :param i: 当前的索引
    :param n: 数组的长度
    :return:
    """
    root = None
    # terminator
    if i >= n or i < 0 or array[i] is None:
        return root

    # current level logic
    root = TreeNode(array[i])

    # drill down 创建左右孩子的结点
    root.left = create_tree(array, 2 * i + 1, n)
    root.right = create_tree(array, 2 * i + 2, n)
    return root


def preorder(root: TreeNode):
    if not root:
        return
    print(f'{root.val}', end=' ')
    preorder(root.left)
    preorder(root.right)




if __name__ == '__main__':
    array = [1, 2, 3, None, 5, None, None]

    root = create_tree(array=array, i=0, n=len(array))

    # preorder(root)
    # print()

    r = Solution().binaryTreePaths(root=root)
    print(r)

    pass

解法2 递归法

递归三部曲

第一确定递归条件, 找到递归条件后 收集结果 返回

第二 当前层 处理逻辑

第三 drill down 到下层

第四 reverse current level status

class Solution:
    def binaryTreePaths(self, root: TreeNode) -> List[str]:
        self.result = []
        if not root:
            return self.result
        level = 0
        cur_result = []
        self._generate(root=root, level=level, cur_result=cur_result)

        return self.result

    def _generate(self, root: TreeNode, level, cur_result: List):

        #  terminator
        if root.left is None and root.right is None:
            cur_result.append(str(root.val))
            r = self._generate_path(cur_result)
            # print(r)
            self.result.append(r)
            return

        # current  logic
        cur_result.append(str(root.val))

        #  drill down
        if root.left:
            self._generate(root.left, level + 1, cur_result)
            # reverse the current level
            cur_result.pop(-1)

        if root.right:
            self._generate(root.right, level + 1, cur_result)
            # reverse the current level
            cur_result.pop(-1)

    def _generate_path(self, result: List):
        if not result:
            return
        return "->".join(result)


解法2-1 递归

上面的递归中每次 保存一个结点, 之后 要回溯cur_result,这里换成一种方法,每次传入一个字符串,作为当前遍历的结果,每次递归的时候先把字符串生成好,由于Python中字符串是不可变的,所以每次进入递归的时
只是复制了一次,每层递归相互不影响,也就避免了回溯逻辑。即 reverse the current level 这样的逻辑。 同时 解法2中level并没有用到,因为到叶子结点的长度 我们无法提前知道,而我们的递归结束条件是判断当前结点的 左 右孩子是否为空。

# -*- coding: utf-8 -*-

from typing import List, Optional

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


def create_tree(array: List, i: int, n: int) -> Optional[TreeNode]:
    """
    :param array: 完全二叉树 对应的数组
    :param i: 当前的索引
    :param n: 数组的长度
    :return:
    """
    root = None
    # terminator
    if i >= n or i < 0 or array[i] is None:
        return root

    # current level logic
    root = TreeNode(array[i])

    # drill down 创建左右孩子的结点
    root.left = create_tree(array, 2 * i + 1, n)
    root.right = create_tree(array, 2 * i + 2, n)
    return root


def preorder(root: TreeNode):
    if not root:
        return
    print(f'{root.val}', end=' ')
    preorder(root.left)
    preorder(root.right)


class Solution:
    def binaryTreePaths(self, root: TreeNode) -> List[str]:
        self.result = []
        if not root:
            return self.result
        cur_result = ""
        self._generate(root=root, cur_result=cur_result)

        return self.result

    def _generate(self, root: TreeNode, cur_result: str):
        if not root:
            return
        if root.left is None and root.right is None:
            cur_result += str(root.val)
            self.result.append(cur_result)
            return

        cur_result = cur_result + str(root.val) + "->"
        self._generate(root.left, cur_result)
        self._generate(root.right, cur_result)


if __name__ == '__main__':
    array = [1, 2, 3, None, 5, None, None]

    root = create_tree(array=array, i=0, n=len(array))

    r = Solution().binaryTreePaths(root=root)
    print(r)

    pass

解法2-2 递归解法

甚至可以这样写, 不需要直接进入 roo.left ,root.right ,如果没有就没有必要进入了,所以可以先判断一下,在进入递归。 同时递归终止条件 就不需要 判断 root 是否为空 这个判断,只要看 当前结点 左右孩子是否为空即可。

class Solution:
    def binaryTreePaths(self, root: TreeNode) -> List[str]:
        self.result = []
        if not root:
            return self.result
        cur_result = ""
        self._generate(root=root, cur_result=cur_result)

        return self.result

    def _generate(self, root: TreeNode, cur_result: str):
        if root.left is None and root.right is None:
            cur_result += str(root.val)
            self.result.append(cur_result)
            return

        cur_result = cur_result + str(root.val) + "->"

        if root.left:
            self._generate(root.left, cur_result)
        if root.right:
            self._generate(root.right, cur_result)

解法3 广度优先搜索

​ 广度优先搜索,只要遍历结点的时候每次 只保留当前路径结果,当遍历到叶子结点的时候,收集结果即可。

# -*- coding: utf-8 -*-

# Definition for a binary tree node.
from collections import deque
from typing import List, Optional


class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


def create_tree(array: List, i: int, n: int) -> Optional[TreeNode]:
    """
    :param array: 完全二叉树 对应的数组
    :param i: 当前的索引
    :param n: 数组的长度
    :return:
    """
    root = None
    # terminator
    if i >= n or i < 0 or array[i] is None:
        return root

    # current level logic
    root = TreeNode(array[i])

    # drill down 创建左右孩子的结点
    root.left = create_tree(array, 2 * i + 1, n)
    root.right = create_tree(array, 2 * i + 2, n)
    return root


def preorder(root: TreeNode):
    if not root:
        return
    print(f'{root.val}', end=' ')
    preorder(root.left)
    preorder(root.right)


class Solution:
    def binaryTreePaths(self, root: TreeNode) -> List[str]:
        self.result = []
        if not root:
            return self.result

        que = deque()

        #  入队列 当前结点 以及当前结点的 val
        que.append(root)
        que.append(str(root.val))
        result = []

        while que:

            node = que.popleft()
            path = que.popleft()
            if node.left is None and node.right is None:
                result.append(path)

            if node.left:
                que.append(node.left)
                que.append(path + "->" + str(node.left.val))
            if node.right:
                que.append(node.right)
                que.append(path + "->" + str(node.right.val))

        return result

if __name__ == '__main__':
    array = [1, 2, 3, None, 5, None, None]

    root = create_tree(array=array, i=0, n=len(array))

    # preorder(root)
    # print()
    r = Solution().binaryTreePaths(root=root)
    print(r)
    pass

Day 20220303 第二次总结 二叉树遍历

解法1 -递归

这里采用先序遍历法

# -*- coding: utf-8 -*-
from typing import List, Optional


class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


class Solution:
    """
    递归法 + 回溯
    """
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        self.all_result = []
        cur_result = []
        self._preorder(root, cur_result)
        return self._build_path(self.all_result)
        pass

    @staticmethod
    def _build_path(results: List) -> List:
        new_result = []
        for result in results:
            item = '->'.join(result)
            new_result.append(item)
        return new_result

    def _preorder(self, root: Optional[TreeNode], cur_result: List):
        if not root:
            return
        # process current level
        cur_result.append(str(root.val))

        if root.left is None and root.right is None:
            self.all_result.append(cur_result.copy())
            return

        if root.left:
            # drill down
            self._preorder(root.left, cur_result)
            # reverse the current level status
            cur_result.pop(-1)

        if root.right:
            # drill down
            self._preorder(root.right, cur_result)
            # reverse the current level status
            cur_result.pop(-1)

解法2 递归的 迭代写法

使用栈 来模拟递归过程

# -*- coding: utf-8 -*-
from typing import List, Optional, Union


class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


class Solution:
    """
    使用迭代法

    使用栈 来模拟先序遍历
    """

    def binaryTreePaths(self, root: Optional[TreeNode]) -> Union[list[list], list[str]]:
        all_result = []
        if not root:
            return all_result

        stack = [(root, str(root.val))]

        while stack:
            node, cur_result = stack.pop()
            cur_result: str
            node: Optional[TreeNode]

            # 到达叶子结点
            if node.left is None and node.right is None:
                all_result.append(cur_result)

            if node.right:
                stack.append((node.right, cur_result + '->' + str(node.right.val)))

            if node.left:
                stack.append((node.left, cur_result + '->' + str(node.left.val)))
        return all_result
        pass

解法3 广度优先搜索

这里使用bfs 搜索 遍历结点的时候,顺便 记录 遍历到当前结点的路径。

# -*- coding: utf-8 -*-
from collections import deque
from typing import List, Optional
from typing import Union


class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


class Solution:
    """

    广度优先搜索 BFS
    """

    def binaryTreePaths(self, root: Optional[TreeNode]) -> Union[list[list], list[str]]:
        all_result = []
        if not root:
            return all_result
            
        que = deque()
        que.append((root, str(root.val)))

        while que:
            node, cur_result = que.popleft()
            # 到达叶子结点
            if node.left is None and node.right is None:
                all_result.append(cur_result)

            if node.left:
                que.append((node.left, cur_result + '->' + str(node.left.val)))

            if node.right:
                que.append((node.right, cur_result + '->' + str(node.right.val)))

        return all_result

参考文档

二叉树的递归遍历

前序遍历-迭代法

二叉树的层序遍历

分享快乐,留住感动. '2022-03-03 22:50:27' --frank
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值