257 Binary Tree Paths

原题链接:Binary Tree Paths

一道新题,我想了好久也不会。。。TnT
以下代码是在Leetcode官方论坛里看到的,非常好:

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

class Solution:
    # @param {TreeNode} root
    # @return {string[]}
    def binaryTreePaths(self, root):
        if not root:
            return []
        return [str(root.val) + '->' + path
                for kid in (root.left, root.right) if kid
                for path in self.binaryTreePaths(kid)] or [str(root.val)]

代码非常简短。
讲解如下:
首先判断root是否为空,如果不存在这个root即 为空),则返回一个空的list。
然后采用递归的方法。第二个return中的两个for等价于嵌套,之所以不写在同一行是为了提高可读性。第一个for循环表示在root的左右子树中选择一个,并且不能是空的子树;然后,第二个for就是在该子树中利用递归方法。
最后的or [str(root.val)]是只有一个根节点的情况时(传入的树只有根节点时,或者在递归当中会出现这种情况),不需要显示'->',所以直接返回根节点的值。

我们现在来仔细地分析一下这个递归为什么是合理的:
第一眼看上去,最后一块代码

return [str(root.val) + '->' + path
    for kid in (root.left, root.right) if kid
    for path in self.binaryTreePaths(kid)] or [str(root.val)]

返回的只是其中一条"root-to-leaf path",并不是所有条"root-to-leaf path"。因为有一个+ path,后面的两个for都是为这个path服务的。
但是我们注意观察最后的or [str(root.val)],由于这道题要返回的是"root-to-leaf path",所以一定会走到叶节点才返回,那么叶节点的特点是什么呢?没有左子树与右子树。所以,在递归中一定会执行到最后的or [str(root.val)]。最后的for循环是for path in XXXX,所以or [str(root.val)]得到的字符串两边的(代表list的)框框也不用担心了。
如果还是不明白,参见以下代码以及对应的输出:

257 Binary Tree Paths_第1张图片

你可能感兴趣的:(257 Binary Tree Paths)