# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children if children is not None else []
class Solution:
def postorder(self, root: 'Node') -> List[int]:
result = []
def dfs(node):
if not node:
return
for child in node.children:
dfs(child)
result.append(node.val)
dfs(root)
return result
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> children;
Node() {}
Node(int _val) {
val = _val;
}
Node(int _val, vector<Node*> _children) {
val = _val;
children = _children;
}
};
class Solution {
public:
vector<int> postorder(Node* root) {
vector<int> result;
dfs(root, result);
return result;
}
void dfs(Node* node, vector<int>& result) {
if (!node) return;
for (Node* child : node->children) {
dfs(child, result);
}
result.push_back(node->val);
}
};
import java.util.*;
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int val) {
this.val = val;
}
public Node(int val, List<Node> children) {
this.val = val;
this.children = children;
}
}
class Solution {
public List<Integer> postorder(Node root) {
List<Integer> result = new ArrayList<>();
dfs(root, result);
return result;
}
private void dfs(Node node, List<Integer> result) {
if (node == null) return;
for (Node child : node.children) {
dfs(child, result);
}
result.add(node.val);
}
}
/**
* // Definition for a Node.
* function Node(val, children) {
* this.val = val;
* this.children = children || [];
* };
*/
/**
* @param {Node|null} root
* @return {number[]}
*/
var postorder = function(root) {
const result = [];
function dfs(node) {
if (!node) return;
for (const child of node.children) {
dfs(child);
}
result.push(node.val);
}
dfs(root);
return result;
};
Given the root of an N-ary tree, return the postorder traversal of its nodes' values. An N-ary tree is a tree in which each node can have zero or more children. In postorder traversal, you recursively visit all the children from left to right, and then visit the node itself.
root
node representing the root of the N-ary tree.root
is null
), return an empty list.To solve this problem, we need to understand how postorder traversal works for an N-ary tree. In a binary tree, postorder means left child, right child, then node. For an N-ary tree, we generalize this to: visit all children in order, then the node itself.
The brute-force idea is to use recursion: for each node, recursively traverse all its children, and after that, add the node's value to the result. This is a natural fit for recursion because the tree's structure is inherently recursive.
If we wanted to optimize or do this iteratively, we could use a stack to simulate the call stack, but recursion is simple and effective for this problem unless the tree is very deep.
Let's outline the step-by-step solution for postorder traversal of an N-ary tree:
null
, return immediately. This handles empty trees.
children
list, recursively perform postorder traversal.
We use recursion because it matches the tree's structure and keeps the code clean. In each recursive call, we process all the children first (from left to right), and then the node itself, which is exactly what postorder requires.
If you want to avoid recursion (for very deep trees), you can use an explicit stack, but recursion is preferred for clarity and simplicity in most interview scenarios.
Let's walk through an example. Suppose the N-ary tree is:
1 / | \ 3 2 4 / \ 5 6
The postorder traversal should be: [5, 6, 3, 2, 4, 1]
The result builds up as follows: [5, 6, 3, 2, 4, 1]
In both cases, the algorithm is efficient and optimal for this problem.
The N-ary Tree Postorder Traversal problem is a classic example of recursive tree processing. By traversing all children before visiting the node itself, we achieve postorder traversal. The recursive approach is natural and efficient, with both time and space complexity proportional to the number of nodes in the tree. This problem reinforces the value of recursion for hierarchical data structures and highlights the simplicity and elegance of postorder traversal in trees of arbitrary branching factor.