[LeetCode] 145. Binary Tree Postorder Traversal

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

Example:

Input: [1,null,2,3]
   1
    
     2
    /
   3

Output: [3,2,1]

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

二叉树的后序遍历。后序遍历我记为左 - 右 - 根

依然用GeeksforGeeks的例子来描述如何做后序遍历吧。

[LeetCode] 145. Binary Tree Postorder Traversal

 Postorder (Left, Right, Root) : 4 5 2 3 1

依然是迭代和递归两种做法,两种做法的时间复杂度均是O(n),空间复杂度均是O(h)

递归没什么好讲的,直接上代码。

JavaScript实现

 1 /**
 2  * @param {TreeNode} root
 3  * @return {number[]}
 4  */
 5 var postorderTraversal = function(root) {
 6     let res = [];
 7     if (root === null) return res;
 8     helper(res, root);
 9     return res;
10 };
11 
12 var helper = function(res, root) {
13     if (root === null) return;
14     helper(res, root.left);
15     helper(res, root.right);
16     res.push(root.val);
17 };

Java实现

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

迭代

思路是需要用到一个栈和一个队列,队列用来存最后的结果。在JS中,队列可以用array来表示;在Java中,这个队列就只能用 LinkedList 表示了,因为一般我们用到的 ArrayList 只能将节点加入list的尾部。遍历节点的时候,先将 root 节点放进栈,弹出的时候,将弹出的节点放进队列的头部(unshift/addFirst)。再看当前节点是否有左右孩子,若有则分别放进栈,先左后右。先左后右放进栈之后弹出来的时候会是先右后左,但是因为放到结果集的时候是从队列的头部放进去所以可以这样做,而无需像 preorder 那样先右后左。需要注意的是当把当前节点 cur 加入到结果集的时候,要加在结果集的最前面而不是最后。这也就是为什么需要用到链表的原因。放进去的顺序会类似这样。

step 1, [root]

step 2, [root.right, root]

step 3, [root.left, root.right, root]

JavaScript实现

 1 /**
 2  * @param {TreeNode} root
 3  * @return {number[]}
 4  */
 5 var postorderTraversal = function (root) {
 6     let res = [];
 7     if (root === null) return res;
 8     let stack = [];
 9     stack.push(root);
10     while (stack.length > 0) {
11         let cur = stack.pop();
12         res.unshift(cur.val);
13         if (cur.left) {
14             stack.push(cur.left);
15         }
16         if (cur.right) {
17             stack.push(cur.right);
18         }
19     }
20     return res;
21 };

Java实现

 1 /**
 2  * Definition for a binary tree node.
 3  * public class TreeNode {
 4  *     int val;
 5  *     TreeNode left;
 6  *     TreeNode right;
 7  *     TreeNode(int x) { val = x; }
 8  * }
 9  */
10 class Solution {
11     public List<Integer> postorderTraversal(TreeNode root) {
12         LinkedList<Integer> res = new LinkedList<>();
13         if (root == null) return res;
14         Stack<TreeNode> stack = new Stack<>();
15         stack.push(root);
16         while (!stack.isEmpty()) {
17             TreeNode cur = stack.pop();
18             res.addFirst(cur.val);
19             if (cur.left != null) stack.push(cur.left);
20             if (cur.right != null) stack.push(cur.right);
21         }
22         return res;
23     }
24 }

树的遍历

94. Binary Tree Inorder Traversal

144. Binary Tree Preorder Traversal

145. Binary Tree Postorder Traversal

LeetCode 题目总结