版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dpengwang/article/details/88166876
先序遍历N叉树
方法1 带有helper 函数的递归
递归。用全局变量+递归
class Solution(object):
def preorder(self, root):
"""
:type root: Node
:rtype: List[int]
"""
self.res = []
self.DFS(root)
return self.res
def DFS(self, root):
if root == None:
return
self.res.append(root.val)
for child in root.children:
self.DFS(child)
方法2 不用help函数的递归
定义好return 的变量就能再不使用help函数的情况下完成递归
class Solution2(object):
def preorder(self, root):
"""
:type root: Node
:rtype: List[int]
"""
res = []
if root == None:
return res
else:
res.append(root.val)
for child in root.children:
res = res + self.preorder(child)
return res
方法3 栈
先序遍历可以用栈实现,而且不需要指针,越深越左的节点首先访问,我们对于每个节点,先访问它,然后将它的孩子从右往左入栈,这样左边的孩子后入栈就会先被弹出访问。
因为是先序遍历,可以在不使用额外指针的情况下完全通过压栈出栈来实现。
class Solution3(object):
def preorder(self, root):
"""
:type root: Node
:rtype: List[int]
"""
res = []
if root == None:
return res
stack = [root]
while(len(stack)):
node = stack.pop()
res.append(node.val)
for child in node.children[::-1]:
stack.append(child)
return res
方法4 栈+dict
一种更通用的方法:因为是先序遍历,所以对于某个节点的孩子节点,我们要从左往右按顺序访问。所以用一个字典记录当前已经访问过的孩子节点的index,如果该下次访问的index值大于孩子的长度,那么说明当前节点的孩子已经访问完了。
我们用一个pNode指针指向当前访问的节点,如果pNode指向None说明已经当前节点没有孩子或者当前节点的孩子已经被访问完了,那么就可以返回到当前节点的父节点,再查找父节点下一个需要被访问的孩子节点。
这样做的比方法3的好处在于不用一次性把所有节点都压入栈
class Solution4(object):
def preorder(self, root):
"""
:type root: Node
:rtype: List[int]
"""
if root == None:
return []
dictionary = {}
res = []
stack = []
pNode = root
while(len(stack) or pNode):
if pNode:
res.append(pNode.val)
if pNode.children != []:
stack.append(pNode)
dictionary[pNode] = 0
pNode = pNode.children[0]
else:
#令pNode == None,使得下一次访问其父节点的其他孩子
pNode = None
else:
pNode = stack[-1]
# 理论上下个孩子的index
dictionary[pNode] +=1
# 说明没有孩子可以访问了
if dictionary[pNode] == len(pNode.children):
stack.pop()
pNode = None
else:
pNode = pNode.children[dictionary[pNode]]
return res