"""
# 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 preorder(self, root: 'Node') -> List[int]:
result = []
def dfs(node):
if not node:
return
result.append(node.val)
for child in node.children:
dfs(child)
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> preorder(Node* root) {
vector<int> result;
dfs(root, result);
return result;
}
private:
void dfs(Node* node, vector<int>& result) {
if (!node) return;
result.push_back(node->val);
for (auto child : node->children) {
dfs(child, result);
}
}
};
/*
// 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> preorder(Node root) {
List<Integer> result = new ArrayList<>();
dfs(root, result);
return result;
}
private void dfs(Node node, List<Integer> result) {
if (node == null) return;
result.add(node.val);
for (Node child : node.children) {
dfs(child, result);
}
}
}
/**
* // Definition for a Node.
* function Node(val, children) {
* this.val = val;
* this.children = children || [];
* };
*/
/**
* @param {Node|null} root
* @return {number[]}
*/
var preorder = function(root) {
const result = [];
function dfs(node) {
if (!node) return;
result.push(node.val);
for (const child of node.children) {
dfs(child);
}
}
dfs(root);
return result;
};
You are given the root of an N-ary tree, where each node has a value and a list of children nodes. Your task is to return the preorder traversal of its nodes' values as a list.
root
node, and you must return a list of integers representing the node values in preorder.
val
(integer) and a children
(list of Node objects).
To solve this problem, we need to understand how preorder traversal works for trees. In binary trees, preorder means: visit the root, then the left subtree, then the right subtree. In an N-ary tree, instead of just two children, each node can have zero or more children, and we must visit them in order.
The traversal is recursive in nature: for each node, process its value, then recursively process each of its children from left to right. A brute-force approach would be to manually manage which nodes to visit next, but recursion naturally fits this problem.
Alternatively, we could use an explicit stack to simulate recursion, but recursion is more straightforward here and matches the problem's recursive structure.
dfs
for "depth-first search") that takes a node as input.
null
(or None
), return immediately. This is the base case for recursion.
children
list and recursively call the helper function on each child.
root
node.
We use recursion because it naturally expresses the "process the root, then each child" logic. The result list is built up as we visit each node in the correct order.
Suppose the tree is:
1 / | \ 3 2 4 / \ 5 6
The preorder traversal should return [1, 3, 5, 6, 2, 4]
.
[1]
).[1, 3]
).[1, 3, 5]
).[1, 3, 5, 6]
).[1, 3, 5, 6, 2]
).[1, 3, 5, 6, 2, 4]
).At each step, we process the current node and then its children recursively, building the result in the correct order.
The N-ary Tree Preorder Traversal problem is a classic example of using recursion to traverse tree-like data structures. By processing the root node first and then recursively visiting each child, we can collect the nodes' values in the correct preorder sequence. The recursive solution is both elegant and efficient, requiring only a simple helper function and a result list. This approach leverages the natural recursive structure of trees and is optimal in both time and space for this problem.