一、题目描述
Given an n-ary tree, return the postorder traversal of its nodes' values.
Nary-Tree input serialization is represented in their level order traversal,
each group of children is separated by the null value (See examples).
Follow up: Recursive solution is trivial, could you do it iteratively?
Input: root = [1,null,3,2,4,null,5,6]
Output: [5,6,3,2,4,1]
二、题解
方法一:递归
LinkedList<Integer> resList = null;
//先节点后跟
public List<Integer> postorder(Node root) {
dfs(root);
return resList;
}
private void dfs(Node root) {
if (root == null)
return;
for (Node child : root.children) {
dfs(child);
}
resList.add(root.val);
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,
方法二:迭代(反转)
后序遍历就是最后遍历根节点,基于这一点,我们可以把根节点的 val 添加在列表的末尾,即 addFirst。
宏观上,我们把前序遍历压栈 push 顺序(右左)改成(左右),遍历以后的序列(根右左)反转过来就是后序(左右根).
private void dfs1(Node root) {
if (root == null)
return;
Stack<Node> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
Node node = stack.pop();
resList.add(node.val);
//压榨:左右
for (Node child : node.children) {
stack.push(child);
}
}
Collections.reverse(resList);
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,
双端队列(迭代)
也可以不用把整条列表都反转,这样太耗费时间,取而代之的是,取出元素时,我们从队列 deque 的尾巴取出,这样可以保证我们拿到的是最左边,但添加进列表 resList 时,却是最右边的。
private void dfs2(Node root) {
if(root == null)
return;
Deque<Node> deque = new LinkedList<>();
deque.add(root);
while (!deque.isEmpty()) {
Node node = deque.removeLast();
resList.addFirst(node.val);
for (Node child : node.children) {
deque.add(child);
}
}
}
来源:CSDN
作者:PANjj99
链接:https://blog.csdn.net/qq_43539599/article/details/104501047