原題鏈接: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循環(huán)表示在root的左右子樹中選擇一個,并且不能是空的子樹;然后,第二個for就是在該子樹中利用遞歸方法。
最后的or [str(root.val)]是只有一個根節(jié)點(diǎn)的情況時(傳入的樹只有根節(jié)點(diǎn)時,或者在遞歸當(dāng)中會出現(xiàn)這種情況),不需要顯示'->',所以直接返回根節(jié)點(diǎn)的值。
我們現(xiàn)在來仔細(xì)地分析一下這個遞歸為什么是合理的:
第一眼看上去,最后一塊代碼
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"。因?yàn)橛幸粋€
+ path,后面的兩個for都是為這個path服務(wù)的。
但是我們注意觀察最后的or [str(root.val)],由于這道題要返回的是"root-to-leaf path",所以一定會走到葉節(jié)點(diǎn)才返回,那么葉節(jié)點(diǎn)的特點(diǎn)是什么呢?沒有左子樹與右子樹。所以,在遞歸中一定會執(zhí)行到最后的or [str(root.val)]。最后的for循環(huán)是for path in XXXX,所以or [str(root.val)]得到的字符串兩邊的(代表list的)框框也不用擔(dān)心了。
如果還是不明白,參見以下代碼以及對應(yīng)的輸出:
