标签:epo null repos 结果 构造二叉树 self 验证 ack 深度
二叉树的前序/中序/后序遍历的非递归描述一般适合用深度优先搜索 (DFS, depth-first search), 并使用栈的数据结构.
版本1 递归
from typing import List
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
res = []
def dfs(root):
if not root:
return None
res.append(root.val)
dfs(root.left)
dfs(root.right)
dfs(root)
return res
版本2 递归
class Solution:
def __init__(self):
self.res = []
def preorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
self.res.append(root.val)
self.preorderTraversal(root.left)
self.preorderTraversal(root.right)
return self.res
版本3 非递归
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
res = []
stack_node = []
while root or stack_node:
if root:
res.append(root.val)
stack_node.append(root.right)
root = root.left
else:
root = stack_node.pop()
return res
from typing import List
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
res = []
stack_node = []
while root or stack_node:
if root:
stack_node.append(root)
root = root.left
else:
root = stack_node.pop()
res.append(root.val)
root = root.right
return res
from typing import List
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
res = []
stack_node = []
seen = None
while root or stack_node:
while root:
stack_node.append(root)
root = root.left
root = stack_node.pop()
if not root.right or root.right is seen:
res.append(root.val)
seen = root
root = None
else:
stack_node.append(root)
root = root.right
return res
示例:
二叉树: [3,9,20,null,null,15,7],
3
/ 9 20
/ 15 7
返回其层序遍历结果:
[
[3],
[9,20],
[15,7]
]
二叉树的层序遍历一般适合用广度优先搜索 (BFS, breadth-first search), 并使用队列的数据结构.
from typing import List
from collections import deque
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
res = []
queue = deque()
queue.append(root)
while queue:
temp = []
for i in range(len(queue)):
cur = queue.popleft()
temp.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
res.append(temp)
return res
示例:
二叉树: [3,9,20,null,null,15,7],
3
/ 9 20
/ 15 7
返回锯齿形层序遍历如下:
[
[3],
[20,9],
[15,7]
]
版本1
from typing import List
from collections import deque
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
res = []
queue = deque()
queue.append(root)
reverse = True
while queue:
temp = []
reverse = not reverse
for i in range(len(queue)):
cur = queue.popleft()
temp.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
if reverse:
res.append(temp[::-1])
else:
res.append(temp)
return res
版本2 temp 修改为双向队列结构
class Solution:
def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
res = []
queue = deque()
queue.append(root)
reverse = True
while queue:
temp = deque()
reverse = not reverse
for i in range(len(queue)):
cur = queue.popleft()
if not reverse:
temp.append(cur.val)
else:
temp.appendleft(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
res.append(list(temp))
return res
示例:
二叉树: [3,9,20,null,null,15,7],
3
/ 9 20
/ 15 7
返回其自底向上的层序遍历为:
[
[15,7],
[9,20],
[3]
]
from typing import List
from collections import deque
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def levelOrderBottom(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
res = deque()
queue = deque()
queue.append(root)
while queue:
temp = []
for _ in range(len(queue)):
cur = queue.popleft()
temp.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
res.appendleft(temp)
return list(res)
注: 遍历中的值是不同的正整数
给出:
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ 9 20
/ 15 7
from typing import List
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
if len(preorder) == 0:
return None
root = TreeNode(preorder[0])
root_id = inorder.index(preorder[0])
root.left = self.buildTree(preorder[1:root_id+1], inorder[:root_id])
root.right = self.buildTree(preorder[root_id+1:], inorder[root_id+1:])
return root
给出:
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
3
/ 9 20
/ 15 7
from typing import List
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
if len(inorder) == 0:
return None
root = TreeNode(postorder[-1])
root_id = inorder.index(postorder[-1])
root.left = self.buildTree(inorder[:root_id], postorder[:root_id])
root.right = self.buildTree(inorder[root_id+1:], postorder[root_id:-1])
return root
给出:
前序遍历 preorder = [3,9,20,15,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
3
/ 9 20
/ 15 7
from typing import List
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def constructFromPrePost(self, pre: List[int], post: List[int]) -> TreeNode:
if len(pre) == 0:
return None
root = TreeNode(pre[0])
if len(pre) == 1:
return root
right_id = pre.index(post[-2])
root.left = self.constructFromPrePost(pre[1:right_id], post[:right_id-1])
root.right = self.constructFromPrePost(pre[right_id:], post[right_id-1:-1])
return root
给你二叉树的根结点 root, 请你将它展开为一个单链表:
展开后的单链表应该同样使用 TreeNode, 其中 right 子指针指向链表中下一个结点, 而左子指针始终为 null.
展开后的单链表应该与二叉树先序遍历顺序相同.
输入: root = [1,2,5,3,4,null,6]
输出: [1,null,2,null,3,null,4,null,5,null,6]
版本1 递归, 时间 O(n), 空间 O(n)
from typing import List
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
def dfs(root):
if not root:
return None
list_node.append(root)
dfs(root.left)
dfs(root.right)
list_node = []
dfs(root)
list_node.append(None)
for i in range(len(list_node)-1):
list_node[i].left = None
list_node[i].right = list_node[i+1]
return list_node[0]
版本2 迭代与展开同步进行, 时间 O(n), 空间 O(1)
class Solution:
def flatten(self, root: TreeNode) -> None:
if not root:
return None
stack_node = []
pre = None
cur = root
while cur or stack_node:
if cur:
pre = cur
temp = cur.left
cur.left = None
stack_node.append(cur.right)
cur = temp
else:
cur = stack_node.pop()
pre.right = cur
return root
LeetCode.剑指 Offer 33. 二叉搜索树的后序遍历序列
输入一个整数数组, 判断该数组是不是某二叉搜索树的后序遍历结果. 如果是则返回 true, 否则返回 false. 假设输入的数组的任意两个数字都互不相同.
参考以下这颗二叉搜索树:
5
/ 2 6
/ 1 3
输入: [1,6,3,2,5]
输出: false
输入: [1,3,2,6,5]
输出: true
class Solution:
def verifyPostorder(self, postorder: List[int]) -> bool:
if len(postorder) == 0:
return True
root_val = postorder[-1]
i = 0
while postorder[i] < root_val:
i += 1
j = i
while postorder[j] > root_val:
j += 1
if j != len(postorder) - 1:
return False
left = True
if i > 0:
left = self.verifyPostorder(postorder[:i])
right = True
if i < j:
right = self.verifyPostorder(postorder[i:-1])
return left and right
返回与给定前序遍历 preorder 相匹配的二叉搜索树(binary search tree)的根结点
输入: [8,5,1,7,10,12]
输出: [8,5,10,1,7,null,12]
from typing import List
class Node:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def bstFromPreorder(self, preorder: List[int]) -> TreeNode:
if len(preorder) == 0:
return None
root = TreeNode(preorder[0])
id_right = 0
while id_right < len(preorder) and preorder[id_right] <= root.val:
id_right += 1
root.left = self.bstFromPreorder(preorder[1:id_right])
root.right = self.bstFromPreorder(preorder[id_right:])
return root
另外一种方法是通过前序遍历与中序遍历构造二叉搜索树, 此时二叉搜索树的中序遍历就是树中所有的元素的值的升序排序.
标签:epo null repos 结果 构造二叉树 self 验证 ack 深度
原文地址:https://www.cnblogs.com/funmore233/p/14610552.html