Easy
题目描述
给定一个 N 叉树,返回其节点值的前序遍历。
N 叉树输入按层序遍历序列化表示,每组子节点都由 null 值分隔(参见示例)。
示例 1:
输入:root = [1,null,3,2,4,null,5,6]
输出:[1,3,5,6,2,4]
示例 2:
输入:root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
输出:[1,2,3,6,7,11,14,4,8,12,5,9,13,10]
约束条件:
- 树中节点数目在范围 [0, 10^4] 内
- 0 <= Node.val <= 10^4
- N 叉树的高度小于或等于 1000
进阶: 递归解法很简单,你可以通过迭代算法完成吗?
解题思路
解题思路
N 叉树的前序遍历与二叉树的前序遍历类似,遍历顺序为:根节点 → 所有子节点。
方法一:递归解法(推荐)
递归是最直观的解法。对于每个节点:
- 先访问当前节点,将其值加入结果
- 然后递归遍历所有子节点
方法二:迭代解法
使用栈来模拟递归过程:
- 将根节点入栈
- 当栈不为空时,弹出栈顶节点并访问
- 将该节点的所有子节点从右到左入栈(保证左子节点先被访问)
注意:由于栈是后进先出的特性,我们需要从右到左将子节点入栈,这样左边的子节点会先被弹出访问。
两种方法的时间复杂度都是 O(n),空间复杂度在最坏情况下都是 O(h),其中 h 是树的高度。递归解法更简洁直观,迭代解法避免了可能的栈溢出问题。
代码实现
/*
// 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;
if (!root) return result;
stack<Node*> stk;
stk.push(root);
while (!stk.empty()) {
Node* node = stk.top();
stk.pop();
result.push_back(node->val);
// 从右到左入栈,保证左子节点先被访问
for (int i = node->children.size() - 1; i >= 0; i--) {
stk.push(node->children[i]);
}
}
return result;
}
};
"""
# Definition for a Node.
class Node:
def __init__(self, val: Optional[int] = None, children: Optional[List['Node']] = None):
self.val = val
self.children = children
"""
class Solution:
def preorder(self, root: 'Node') -> List[int]:
if not root:
return []
result = []
stack = [root]
while stack:
node = stack.pop()
result.append(node.val)
# 从右到左入栈,保证左子节点先被访问
for child in reversed(node.children):
stack.append(child)
return result
/*
// Definition for a Node.
public class Node {
public int val;
public IList<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val,IList<Node> _children) {
val = _val;
children = _children;
}
}
*/
public class Solution {
public IList<int> Preorder(Node root) {
IList<int> result = new List<int>();
if (root == null) return result;
Stack<Node> stack = new Stack<Node>();
stack.Push(root);
while (stack.Count > 0) {
Node node = stack.Pop();
result.Add(node.val);
// 从右到左入栈,保证左子节点先被访问
for (int i = node.children.Count - 1; i >= 0; i--) {
stack.Push(node.children[i]);
}
}
return 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) {
if (!root) return [];
const result = [];
const stack = [root];
while (stack.length > 0) {
const node = stack.pop();
result.push(node.val);
// 从右到左入栈,保证左子节点先被访问
for (let i = node.children.length - 1; i >= 0; i--) {
stack.push(node.children[i]);
}
}
return result;
};
复杂度分析
| 复杂度类型 | 递归解法 | 迭代解法 |
|---|---|---|
| 时间复杂度 | O(n) | O(n) |
| 空间复杂度 | O(h) | O(h) |
其中 n 是树中节点的总数,h 是树的高度。在最坏情况下(完全不平衡的树),h = n,空间复杂度为 O(n)。