有LeetCode算法/华为OD考试扣扣交流群可加 948025485
可上全网独家的 欧弟OJ系统 练习华子OD、大厂真题
绿色聊天软件戳od1336
了解算法冲刺训练
题目描述
给定一个 n 叉树的根节点 root
,返回 其节点值的 前序遍历 。
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
进阶:递归法很简单,你可以使用迭代法完成此题吗?
解题思路
本题的递归解法无非是将LeetCode144、二叉树的前序遍历 中的
ans.append(node.val)
self.dfs(ans, node.left)
self.dfs(ans, node.right)
改为
self.ans.append(root.val)
for children in root.children:
if children:
self.dfs(children)
即可。即始终维持先访问根节点的值,再递归遍历所有子节点这样的顺序。
迭代法类似二叉树的BFS,只不过是把维护一个队列改为维护一个栈。其核心过程为
stack = [root]
while(len(stack)):
node = stack.pop()
ans.append(node.val)
for children in node.children[::-1]:
if children:
stack.append(children)
return ans
注意每一个子节点入栈的顺序是逆序的,即for children in node.children[::-1]
。
这是由栈后进先出的特定来决定的,对于每一个node
而言,node
的第一个子节点最后入栈,第一个出栈,这样才能确保是结果是子节点从左到右的前序遍历。
另外,由于是前序遍历,访问父节点的始终位于遍历子节点的前面。
代码
方法一:递归法
Python
class Solution:
# 1.递归法
def dfs(self, root: 'Node'):
# 先父节点,后子节点
self.ans.append(root.val)
for children in root.children:
if children:
self.dfs(children)
def preorder(self, root: 'Node') -> List[int]:
if not root:
return []
self.ans = list()
self.dfs(root)
return self.ans
Java
class Solution {
// 递归法
private List<Integer> ans = new ArrayList<>();
private void dfs(Node root) {
if (root == null) return;
// 先父节点,后子节点
ans.add(root.val);
for (Node child : root.children) {
if (child != null) {
dfs(child);
}
}
}
public List<Integer> preorder(Node root) {
if (root == null) return new ArrayList<>();
ans.clear();
dfs(root);
return ans;
}
}
C++
class Solution {
public:
// 递归法
vector<int> ans;
void dfs(Node* root) {
if (!root) return;
// 先父节点,后子节点
ans.push_back(root->val);
for (Node* child : root->children) {
if (child) {
dfs(child);
}
}
}
vector<int> preorder(Node* root) {
if (!root) return {};
ans.clear();
dfs(root);
return ans;
}
};
时空复杂度
时间复杂度:O(N)
。仅需一次遍历整棵树。
空间复杂度:O(``1``)
。忽略递归所调用的编译栈。
方法二:迭代法
Python
class Solution:
def preorder(self, root: 'Node') -> List[int]:
ans = list()
if not root:
return []
stack = [root] # 用栈维护DFS过程
while(len(stack)):
node = stack.pop()
ans.append(node.val)
for children in node.children[::-1]:
if children:
stack.append(children)
return ans
Java
class Solution {
// Iterative Solution
public List<Integer> preorder(Node root) {
List<Integer> ans = new ArrayList<>();
if (root == null)
return ans;
Stack<Node> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
Node node = stack.pop();
ans.add(node.val);
for (int i = node.children.size() - 1; i >= 0; i--) {
if (node.children.get(i) != null) {
stack.push(node.children.get(i));
}
}
}
return ans;
}
}
C++
class Solution {
public:
vector<int> preorder(Node* root) {
vector<int> ans;
if (!root)
return ans;
stack<Node*> stack;
stack.push(root);
while (!stack.empty()) {
Node* node = stack.top();
stack.pop();
ans.push_back(node->val);
for (int i = node->children.size() - 1; i >= 0; i--) {
if (node->children[i] != NULL) {
stack.push(node->children[i]);
}
}
}
return ans;
}
};
时空复杂度
时间复杂度:O(N)
。仅需一次遍历整棵树。
空间复杂度:O(N)
。栈所占最大空间。
华为OD算法/大厂面试高频题算法练习冲刺训练
-
华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务300+同学成功上岸!
-
课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化
-
每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!
-
60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁
-
可上全网独家的欧弟OJ系统练习华子OD、大厂真题
-
可查看链接 大厂真题汇总 & OD真题汇总(持续更新)
-
绿色聊天软件戳
od1336
了解更多