LC-257. 二叉树的所有路径
递归法
这道题是一个简单题,虽然经过一番思考做了上来,但是确实是思维不清晰,所以还是要总结一下。
这道题是记录根节点到叶子节点的路径,最重要的是想明白返回条件。
-
这道题是记录到叶子节点,自然是只有到叶子节点的时候,才会返回,也就是说左右子树都不存在的时候
not root.left and not root.right
。不要对本层节点进行判断,那样会导致对叶子节点的左右子树判断,最后会同一个路径会添加两次。 -
这道题我采用的时先序遍历,体现在最开始遍历的时候就先把
root.val
加入到答案中啦~然后才进行的递归。 -
因为上面是判断了一个节点的左右孩子的存在性,没有判断这个节点是否存在,会出现空节点报错,所以在递归的时候,就先应该判断节点是否存在。**重点:**通过传参的时候用+拼接的方式传参,避免了后面还需要回退的问题,这是个小技巧。也就是说避免了先递归再回溯的问题。
if root.left: func(root.left, tmp + '->' + str(root.left.val)) if root.right: func(root.right, tmp + '->' + str(root.right.val))
-
有人会好奇,如果没有左右孩子都不存在,那么本层的怎么返回呢?其实不会的,因为别忘记了我们最开始就判断了这个节点是不是叶子节点,如果是叶子节点直接添加,如果不是,则必然一个孩子。
代码如下:
class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
res = []
def func(root, tmp):
if not root.left and not root.right:
res.append(tmp)
return
if root.left: func(root.left, tmp + '->' + str(root.left.val))
if root.right: func(root.right, tmp + '->' + str(root.right.val))
func(root, str(root.val))
return res
迭代法
迭代法依然使用前序遍历的方法。这里的主要思想是需要两个栈,同时讲节点和该节点对应的路径保存。什么叫该节点对一个的路径保存呢,意思就是说到这个节点为止,已经路径到哪了,这样如果它还有孩子直接把 这个路径取出,添加上孩子就好了。
以示例为了,假如stack[1] = 2,那么path_st[2] = “1->2”,这样如果到节点5了,只需要取出path_st[2] = "1->2"加上5,并且5是叶子节点,直接添加到最后的result里面就可以了。
代码如下:
from collections import deque
class Solution:
"""二叉树的所有路径 迭代法"""
def binaryTreePaths(self, root: TreeNode) -> List[str]:
# 题目中节点数至少为1
stack, path_st, result = deque([root]), deque(), []
path_st.append(str(root.val))
while stack:
cur = stack.pop()
path = path_st.pop()
# 如果当前节点为叶子节点,添加路径到结果中
if not (cur.left or cur.right):
result.append(path)
if cur.right:
stack.append(cur.right)
path_st.append(path + '->' + str(cur.right.val))
if cur.left:
stack.append(cur.left)
path_st.append(path + '->' + str(cur.left.val))
return result