Leetcode 590. N-ary Tree Postorder Traversal
Problem Explanation:
Given a n-ary tree (a tree where each node can have n children), we are to return a post-order traversal of the tree. In a post-order traversal, we visit each child node before its parent node. We are expected to solve this problem iteratively instead of recursively.
Approach:
The solution uses a Stack-based approach for iterative Post-order traversal.
Post-order traversal for a tree is done by traversing the left subtree, then the right subtree and finally the node itself. However, this problem has a N-ary tree which means each node can have 'n' number of children. So in a postorder traversal, we visit each child node and then the parent node.
The iterative solution is essentially running a loop where we pop a node, visit it and push its children into the stack. But this will result in a root-leaf order since the root node is visited first. To convert this root-leaf order list into a post-order list, we reverse the list after the loop.
Python Solution:
1 2python 3class Solution: 4 def postorder(self, root): 5 if root is None: 6 return [] 7 8 stack, output = [root], [] 9 10 while stack: 11 root = stack.pop() 12 output.append(root.val) 13 stack.extend(root.children) 14 15 return output[::-1]
Java Solution:
1 2java 3class Solution { 4 public List<Integer> postorder(Node root) { 5 LinkedList<Node> stack = new LinkedList<>(); 6 LinkedList<Integer> output = new LinkedList<>(); 7 8 if (root == null) 9 return output; 10 11 stack.add(root); 12 while (!stack.isEmpty()) { 13 Node node = stack.pollLast(); 14 output.addFirst(node.val); 15 stack.addAll(node.children); 16 } 17 return output; 18 } 19}
Javascript Solution:
1 2javascript 3class Solution { 4 postorder(root) { 5 if (root == null) 6 return []; 7 8 const stack = [root]; 9 const output = []; 10 11 while (stack.length) { 12 root = stack.pop(); 13 output.unshift(root.val); 14 stack.push(...root.children); 15 } 16 return output; 17 } 18}
C# Solution:
1 2csharp 3public class Solution { 4 public IList<int> Postorder(Node root) { 5 if (root == null) 6 return new List<int>(); 7 8 List<int> ans = new List<int>(); 9 Stack<Node> stack = new Stack<Node>(); 10 stack.Push(root); 11 12 while(stack.Count > 0){ 13 root = stack.Pop(); 14 ans.Add(root.val); 15 16 var count = root.children.Count; 17 for(int i=0; i<count; i++){ 18 stack.Push(root.children[i]); 19 } 20 } 21 ans.Reverse(); 22 return ans; 23 } 24}
C++ Solution:
1
2cpp
3class Solution {
4public:
5 vector<int> postorder(Node* root) {
6 if (!root)
7 return {};
8
9 vector<int> ans;
10 stack<Node*> stack;
11 stack.push(root);
12
13 while (!stack.empty()) {
14 root = stack.top();
15 stack.pop();
16 ans.push_back(root -> val);
17 for(Node* child : root -> children)
18 stack.push(child);
19 }
20 reverse(ans.begin(), ans.end());
21 return ans;
22 }
23};
Conclusion:
In conclusion, the problem of postorder traversal of an n-ary tree can be solved using a Stack-based approach iteratively. The basic idea is to use a stack for the traversal of the nodes and add the children nodes of the current node to the stack while traversing. Then, reverse the result list after the loop to get the result in post-order.
In this tutorial, we have presented the implementations of this solution in Python, Java, Javascript, C#, and C++. By understanding this approach, anyone will be able to perform a post-order traversal on a n-ary tree iteratively in any of these languages.
The time complexity of this solution is O(n) since every node needs to be visited once where n is the number of nodes in the tree. The space complexity is also O(n) as at most all nodes will be stored in the stack. Although this solution needs a reverse operation at last which costs another round of traversal, it's faster than a recursive method because there's no function call overhead, and it's simpler in concept.
So the key takeaway is that when we are asked to perform tree traversal iteratively, we can always consider using the stack data structure. It mimics the recursive function call stack and helps us control the order of traversal. It is a good practice to use iterative methods which are generally more efficient than recursive methods.
Got a question?ย Ask the Teaching Assistantย anything you don't understand.
Still not clear? Ask in the Forum, ย Discordย orย Submitย the part you don't understand to our editors.