【Leetcode】590. N-ary Tree Postorder Traversal 解题报告

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dpengwang/article/details/88168641

在这里插入图片描述
后续遍历N叉树,也就是先访问子节点再访问父节点。
N叉树的访问没有中序说法,因为没有左右节点的概念,只有父节点和孩子们的访问顺序先后的问题。

方法1 递归

带help函数的递归
class Solution1(object):
    def postorder(self, root):
        """
        :type root: Node
        :rtype: List[int]
        """
        self.res =  []
        self.DFS(root)
        return self.res


    def DFS(self, root):
        if root == None:
            return
        else:
            for child in root.children:
                self.DFS(child)
            self.res.append(root.val)

不带help函数的递归
class Solution1(object):
    def postorder(self, root):
        """
        :type root: Node
        :rtype: List[int]
        """
        res = []
        if root == None:
            return res
        else:
            for child in root.children:
                res = res + self.postorder(child)
            res += [root.val]
        return res

方法2 栈 + 指针

用指针指向上一次访问过的节点,如果上一次访问过的节点是当前节点的最右孩子,即可访问该父节点。这是传统的后续遍历的思想

class Solution2(object):
    def postorder(self, root):
        """
        :type root: Node
        :rtype: List[int]
        """
        if root == None:
            return []
        stack = [root]
        prev = None
        res = []
        while(len(stack)):
            node = stack[-1]
            if node.children == [] or node.children[-1] == prev:
                res.append(node.val)
                prev = node
                stack.pop()
            else:
                for child in node.children[::-1]:
                    stack.append(child)
        return res

方法3 栈 + dict

用dict保存当前节点已被访问过的孩子节点的index,如果访问完了所有的孩子即可访问该父节点

class Solution3(object):
    def postorder(self, root):
        """
        :type root: Node
        :rtype: List[int]
        """
        if root == None:
            return []
        res, stack, pNode, dictionary, prev = [], [], root, {}, None
        while(len(stack) or pNode):
            if pNode:
                # print("a")
                stack.append(pNode)
                if pNode.children != []:
                    dictionary[pNode] = 0
                    pNode = pNode.children[0]
                else:
                    pNode = None
            else:
                pNode = stack[-1]
                if pNode in dictionary and len(pNode.children) > dictionary[pNode]+1:
                    dictionary[pNode] +=1
                    pNode = pNode.children[dictionary[pNode]]
                else:
                    res.append(pNode.val)
                    stack.pop()
                    pNode = None
        return res

小结

对于N叉树的先序后续遍历和二叉树的先序后续遍历有相同也有不同

  • 相同的地方比如:先序遍历两种树的入栈方式都是一样的,后续遍历中也都要用一个prev指示上次访问过的节点
  • 不同点在于:二叉树的先序访问中可以用栈加指针的形式来完成,在N叉树中就没法做到,因为指针无法指示当前孩子的位置。

猜你喜欢

转载自blog.csdn.net/dpengwang/article/details/88168641