【树】C003_N叉树的后序遍历(递归 | 迭代)

爱⌒轻易说出口 提交于 2020-02-25 20:07:47

一、题目描述

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);
}

复杂度分析

  • 时间复杂度:O(N)O(N)
  • 空间复杂度:O(N)O(N)

方法二:迭代(反转)

后序遍历就是最后遍历根节点,基于这一点,我们可以把根节点的 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);
}

复杂度分析

  • 时间复杂度:O(N)O(N)
  • 空间复杂度:O(N)O(N)

双端队列(迭代)

也可以不用把整条列表都反转,这样太耗费时间,取而代之的是,取出元素时,我们从队列 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);
    }
  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!