有LeetCode算法/华为OD考试扣扣交流群可加 948025485
可上全网独家的 欧弟OJ系统 练习华子OD、大厂真题
绿色聊天软件戳od1336
了解算法冲刺训练
文章目录
- 题目链接
- 题目描述
- 解题思路
- 代码
- Python
- Java
- C++
- 时空复杂度
- 华为OD算法/大厂面试高频题算法练习冲刺训练
题目链接
LeetCode590、 N 叉树的后序遍历
题目描述
给定一个 n 叉树的根节点 root
,返回 其节点值的 后序遍历 。
n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null
分隔(请参见示例)。
示例 1:
输入:root = [1,null,3,2,4,null,5,6]
输出:[5,6,3,2,4,1]
示例 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]
输出:[2,6,14,11,7,3,12,8,4,13,9,10,5,1]
提示:
- 节点总数在范围
[0, 10(4)]
内 0 <= Node.val <= 10(4)
- n 叉树的高度小于或等于
1000
进阶:递归法很简单,你可以使用迭代法完成此题吗?
解题思路
本题的递归解法无非是将LeetCode144、二叉树的前序遍历 中的
self.dfs(ans, node.left)
self.dfs(ans, node.right)
ans.append(node.val)
改为
for children in root.children:if children:self.dfs(children)
self.ans.append(root.val)
即可。即始终维持先递归遍历所有子节点,再访问根节点的值这样的顺序。
对于N
叉树而言,如果我们考虑其对称的N
叉树。以示例一为例如下图所示:
原N
叉树的后序遍历顺序是**:递归地从左往右遍历子节点->访问根节点的值**
如果我们在对称N叉树中进行考虑,想得到和原N
叉树的后序遍历顺序一样的结果,则其过程为**:递归地从右往左遍历子节点->访问根节点的值**
即如下图所示
换句话说,如果我们按照类似【二叉树DFS】LeetCode 589、 N 叉树的前序遍历的迭代法逆序地遍历node.children
,对应的对称N
叉树的遍历是一种类似于后序遍历,但层内是从右往左的遍历。
我们再考虑这棵对称N
叉树的从左往右的前序遍历,会得到原N
叉树的后序遍历的逆序结果,即
所以我们把N
叉树的后序遍历,转换为了其对称N
叉树的前序遍历,最后再取逆序即可。
而对称N
叉树的每层从左往右遍历,等同于其原N
叉树每层从右往左遍历。
所以迭代法类似二叉树的BFS,只不过是把维护一个队列改为维护一个栈。其核心过程为
stack = [root]
while(len(stack)):node = stack.pop()ans.append(node.val)for children in node.children: if children:stack.append(children)
return ans[::-1]
注意每一个子节点入栈的顺序是正序的,即for children in node.children:
。这样可以得到其对称N
叉树的前序遍历结果了。注意最终的返回结果是ans
的逆序结果ans[::-1]
。
代码
Python
"""
# Definition for a Node.
class Node:def __init__(self, val=None, children=None):self.val = valself.children = children
"""class Solution:def postorder(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: # 子节点正序存入if children:stack.append(children)return ans[::-1] # 答案最后要反序
Java
class Solution {public List<Integer> postorder(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 (Node child : node.children) {if (child != null) {stack.push(child);}}}List<Integer> reversedAns = new ArrayList<>();for (int i = ans.size() - 1; i >= 0; i--) {reversedAns.add(ans.get(i));}return reversedAns;}
}
C++
class Solution {
public:vector<int> postorder(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 (Node* child : node->children) {if (child != NULL) {stack.push(child);}}}reverse(ans.begin(), ans.end());return ans;}
};
时空复杂度
时间复杂度:O(N)
。仅需一次遍历整棵树。
空间复杂度:O(N)
。栈所占最大空间。
华为OD算法/大厂面试高频题算法练习冲刺训练
-
华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务300+同学成功上岸!
-
课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化
-
每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!
-
60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁
-
可上全网独家的欧弟OJ系统练习华子OD、大厂真题
-
可查看链接 大厂真题汇总 & OD真题汇总(持续更新)
-
绿色聊天软件戳
od1336
了解更多