题目
给定一个二叉树,返回它的 后序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [3,2,1]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
Related Topics 栈 树
思路
后序遍历:左-右-中
题目也说了递归很简单,使用一个DFS(深度优先遍历),分别按左右中,加到结果列表里。我相信你也可以写得出来。
什么是迭代?
递归是使用函数栈去实现的,也就是自己调用自己。每次调用都需要去开辟方法栈空间,当栈太深时就会出现栈溢出。
那么如何用迭代实现呢?
概念 —— 迭代是重复反馈过程的活动,其目的通常是为了接近并到达所需的目标或结果。 每一次对过程的重复被称为一次迭代
,而每一次迭代得到的结果会被用来作为下一次迭代的初始值。
说白了,就是能用for
、 while
实现的,就别用递归。
一般的能写成递归的都能转化成迭代
,但迭代写完后相对于递归来说没有那么好理解
解法
递归
class Solution {
List<Integer> res ;
public List<Integer> postorderTraversal(TreeNode root) {
res = new ArrayList<>();
dfs(root);
return res;
}
public void dfs(TreeNode node) {
if (node == null) return ;
dfs(node.left);
dfs(node.right);
res.add(node.val);
}
}
迭代
1
/ \
2 3
/ \ / \
4 5 6 7
以上面这棵树为例子,我们要实现按照左边-右边-中间的顺序输出。在这里用栈就很巧妙,每次都推出一个元素,并将左右子树分别压入栈。而推出的这个元素就是根节点,每次拼接到链表的头部。
结合代码走一遍
1
做为根节点,压入栈。
推出1
,将自己的左右节点2
、3
入栈。(按2,3 的顺序入栈)
推出3
,将自己的左右节点6
、7
入栈。
推出7
,7
为叶子节点,无入栈元素
推出6
,6
为叶子节点,无入栈元素
此时右子树已经遍历完。
推出2
,将自己的左右节点4
、5
入栈。(按4,5 的顺序入栈)
推出5
,5
为叶子节点,无入栈元素
推出4
,4
为叶子节点,无入栈元素
完成!栈里已无元素。
这里呢画个图就能一下子明白啥回事!
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
LinkedList<Integer> res = new LinkedList<>();
if (root==null) return res;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode pop = stack.pop();
res.addFirst(pop.val);
if (null!=pop.left) stack.push(pop.left);
if (null!=pop.right) stack.push(pop.right);
}
return res;
}
}