145.Binary Tree Postorder Traversal

Question

Given a binary tree, return the postorder traversal of its nodes’ values.

Example:

1
2
3
4
5
6
7
8
Input: [1,null,2,3]
1
\
2
/
3
Output: [3,2,1]

Follow up: Recursive solution is trivial, could you do it iteratively?

Left, Right, root

Answer

Recursive
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
return recursivePostTraversal(root, res);
}
public List<Integer> recursivePostTraversal(TreeNode root, List<Integer> res){
if(root!=null){
recursivePostTraversal(root.left, res);
recursivePostTraversal(root.right, res);
res.add(root.val);
}
return res;
}
}

Time complexity: O(n), 1ms

Iterative, Using addFirst()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
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 node = stack.pop();
res.addFirst(node.val);
if(node.left!=null)
stack.push(node.left);
if(node.right!=null)
stack.push(node.right);
}
return res;
}
}

Time complexity: O(n), 2ms

push node.left first, then node.right, in this way, will addFirst(node.right), then addFirst(add.left) -> left, right, root

Only LinkedList has method addFirst(Element e)

Iterative, Using LastVisit node
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
LinkedList<Integer> res = new LinkedList<>();
if(root == null)
return res;
Stack<TreeNode> stack = new Stack<>();
TreeNode node = root;
TreeNode lastVisit = root;
while(node != null || !stack.isEmpty()){
while(node!=null){
stack.push(node);
node = node.left;
}
node = stack.peek();
if(node.right==null || node.right==lastVisit){
res.add(node.val);
stack.pop();
lastVisit = node;
node = null;
}
else
node = node.right;
}
return res;
}
}

后序遍历在决定是否可以输出当前节点的值的时候,需要考虑其左右子树是否都已经遍历完成。

所以需要设置一个lastVisit游标。

若lastVisit等于当前考查节点的右子树,表示该节点的左右子树都已经遍历完成,则可以输出当前节点。

并把lastVisit节点设置成当前节点,将当前游标节点node设置为空,下一轮就可以访问栈顶元素。