题目:二叉树的后序遍历
- 给定一个二叉树,返回它的 后序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [3,2,1]
进阶:递归算法很简单,你可以通过迭代算法完成吗?
来源:力扣(LeetCode)第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]: if root is None: return [] stack = [root] res = [] while stack: root = stack.pop() res.append(root.val) if root.left is not None: # 先加左再加右,出栈的时候就是先加右,再加左。 stack.append(root.left) if root.right is not None: stack.append(root.right) return res[::-1]
我自己写的迭代法,内容有点复杂,不是很好理解。
# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution(object): def postorderTraversal(self, root): stack = [] helper = [] res = [] while stack or root: while root: stack.append(root) root = root.left helper.append(stack[-1]) root = stack.pop().right if root is None: res.append(helper.pop().val) while stack and stack[-1].left in helper and helper: res.append(helper.pop().val) while not stack and helper: res.append(helper.pop().val) return res
虽然我的方法写的多了一点,但是速度和官方的一样,甚至有时比官方解法快。
复杂度分析:
- 两种方法相同,都是迭代法:
- 时间复杂度:O(n) n为树的所有节点。
- 空间复杂度:O(n)
总结:
- 再一次遇到逆向工作法,事实证明如果你遇到问题解不开来反向解一下,思路清晰,易于求解。