145. 二叉树的后序遍历
https://leetcode-cn.com/problems/binary-tree-postorder-traversal/
解法一:递归
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
res = []
self.travel(root, res)
return res
def travel(self, root, res): #辅助函数,注意要将结果集作为参数传入,才能在递归中修改结果集
if root:
self.travel(root.left, res)
self.travel(root.right, res)
res.append(root.val)
解法二:用栈。
左右中的顺序,关键是判断左右是否已访问,且是先左后右,才能访问中。用cur表示当前访问,last表示上一次访问。
初始将根放入栈,last初始为根
每次令cur为当前栈顶,但是不弹栈
1)若cur左子非空,且cur左子和右子都不为last,则cur的左子入栈。解释:last是最近弹栈并输出的节点,若last等于cur的左子或右子,说明cur的左子树和右子树都已输出,此时不应将cur的左子入栈。否则说明左子树还没处理,将cur的左子入栈
2)若1不成立,且cur的右子非空,last不为cur的右子,则cur的右子入栈。解释:若last为cur的右子,说明cur的右子已输出,此时不应再将cur的右子入栈,否则说明右子树还没处理,要将cur的右子入栈
3)若1和2都不成立,说明cur的左子和右子都已输出,则将cur弹栈,并将cur标记为last
class Solution:
def postorderTraversal(self, root: TreeNode) :
res = []
last = root #记录上一个访问节点,初始为根
if not root:
return res
s = [root]
while s:
# 取栈顶作为本轮的根节点,注意最后才访问所以不能出栈
cur = s[-1]
# 1. c的左子非空,且左子和右子都没处理过
if cur.left and cur.left != last and cur.right != last:
s.append(cur.left)
# 2. 若1不成立,且c的右子非空,且右子未处理过
elif cur.right and cur.right != last:
s.append(cur.right)
# 3. 若1和2不成立,说明c的左子树和右子树都已处理,将cur弹栈并输出,last标记为cur
else:
cur = s.pop()
res.append(cur.val)
last = cur
return res
最后更新于