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的例子来描述如何做后序遍历吧。
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