📅  最后修改于: 2023-12-03 15:28:53.300000             🧑  作者: Mango
在面试时,树是最常见的数据结构之一,因此树编码问题也是面试过程中必考的题目之一。本文总结了 50 个树编码问题并提供了详细的解释和代码实现,希望能够帮助程序员加强对树的理解和编码能力。
先序遍历是指先遍历节点本身,然后递归地遍历左右子树。常用于生成一个与树结构相同的表达式。
def preorder_traversal(root):
if not root:
return []
stack, res = [root], []
while stack:
node = stack.pop()
res.append(node.val)
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
return res
给定二叉树[1,2,3,None,4,5,6],先序遍历结果为[1,2,None,4,5,None,None,3,None,6,None,None]
中序遍历是指先递归地遍历左子树,然后遍历节点本身,最后递归地遍历右子树。在二叉搜索树上使用中序遍历可以得到有序的结果。
def inorder_traversal(root):
if not root:
return []
stack, res = [], []
while stack or root:
while root:
stack.append(root)
root = root.left
node = stack.pop()
res.append(node.val)
root = node.right
return res
给定二叉树[1,2,3,None,4,5,6],中序遍历结果为[2,4,None,None,5,None,None,1,3,6,None,None,None]
后序遍历是指先递归地遍历左右子树,然后遍历节点本身。常用于先处理子节点,后处理父节点的情形。
def postorder_traversal(root):
if not root:
return []
stack, res = [root], []
while stack:
node = stack.pop()
res.append(node.val)
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return res[::-1]
给定二叉树[1,2,3,None,4,5,6],后序遍历结果为[4,None,5,None,2,6,None,None,3,1]
给定树的前序/中序/后序遍历序列,如何重建二叉树?
def build_tree(preorder, inorder):
if not preorder or not inorder:
return None
root_val = preorder[0]
root = TreeNode(root_val)
idx = inorder.index(root_val)
root.left = build_tree(preorder[1:1 + idx], inorder[:idx])
root.right = build_tree(preorder[1 + idx:], inorder[idx + 1:])
return root
给定树的前序遍历序列[1,2,4,5,3,6]和中序遍历序列[4,2,5,1,3,6],还原二叉树。
def build_tree(inorder, postorder):
if not postorder or not inorder:
return None
root_val = postorder[-1]
root = TreeNode(root_val)
idx = inorder.index(root_val)
root.left = build_tree(inorder[:idx], postorder[:idx])
root.right = build_tree(inorder[idx + 1:], postorder[idx:-1])
return root
给定树的中序遍历序列[4,2,5,1,3,6]和后序遍历序列[4,5,2,6,3,1],还原二叉树。
由于先序遍历顺序为[root, left, right],而后序遍历顺序为[left, right, root],因此可以递归地构建二叉树。
def construct_from_pre_post(pre, post):
if not pre:
return None
root = TreeNode(pre[0])
if len(pre) == 1:
return root
L = post.index(pre[1]) + 1
root.left = construct_from_pre_post(pre[1:L + 1], post[:L])
root.right = construct_from_pre_post(pre[L + 1:], post[L:-1])
return root
给定树的先序遍历序列[1,2,4,5,3,6]和后序遍历序列[4,5,2,6,3,1],还原二叉树。
给定一颗二叉树,返回所有从根到叶的路径。
def binary_tree_paths(root):
if not root:
return []
if not root.left and not root.right:
return [str(root.val)]
paths = []
if root.left:
for path in binary_tree_paths(root.left):
paths.append(str(root.val) + '->' + path)
if root.right:
for path in binary_tree_paths(root.right):
paths.append(str(root.val) + '->' + path)
return paths
给定二叉树[1,2,3,None,5],所有从根到叶的路径为['1->2->5', '1->3']
给定一个非空的二叉树,找到连接树中节点的最大路径和。路径可以以任意顺序访问,但需要按照从父节点到子节点的方向。
def max_path_sum(root):
def dfs(node):
if not node:
return 0
left = max(dfs(node.left), 0)
right = max(dfs(node.right), 0)
nonlocal max_sum
max_sum = max(max_sum, left + node.val + right)
return max(left, right) + node.val
max_sum = float('-inf')
dfs(root)
return max_sum
给定二叉树[1,2,3],最大路径和为6
判断一个二叉树是否是二叉搜索树。
def is_valid_bst(root):
def inorder_traversal(node, inorder):
if not node:
return inorder
inorder = inorder_traversal(node.left, inorder)
inorder.append(node.val)
inorder = inorder_traversal(node.right, inorder)
return inorder
inorder = inorder_traversal(root, [])
return inorder == sorted(list(set(inorder)))
给定二叉树[2,1,3],是二叉搜索树;给定二叉树[5,1,4,None,None,3,6],不是二叉搜索树。
向一个二叉搜索树中插入和删除节点。
class TreeNode:
def __init__(self, val=None, left=None, right=None):
self.val = val
self.left = left
self.right = right
class BST:
def __init__(self):
self.root = None
def insert(self, val):
def helper(node, val):
if not node:
return TreeNode(val)
if node.val > val:
node.left = helper(node.left, val)
else:
node.right = helper(node.right, val)
return node
self.root = helper(self.root, val)
def delete(self, val):
def get_successor(node):
node = node.right
while node.left:
node = node.left
return node
def delete_helper(node, val):
if not node:
return None
if node.val == val:
if not node.left and not node.right:
return None
if not node.left:
return node.right
if not node.right:
return node.left
successor = get_successor(node)
node.val = successor.val
node.right = delete_helper(node.right, successor.val)
elif node.val > val:
node.left = delete_helper(node.left, val)
else:
node.right = delete_helper(node.right, val)
return node
self.root = delete_helper(self.root, val)
插入节点到二叉搜索树,并删除一个节点。
判断一个二叉树是否平衡,即左右子树高度差不能超过 1。
def is_balanced(root):
def helper(node):
if not node:
return 0
left_height = helper(node.left)
right_height = helper(node.right)
nonlocal balanced
if abs(left_height - right_height) > 1:
balanced = False
return max(left_height, right_height) + 1
balanced = True
helper(root)
return balanced
给定二叉树[3,9,20,None,None,15,7],是平衡二叉树;给定二叉树[1,2,2,3,3,None,None,4,4],不是平衡二叉树。
从一个有序数组中构造一颗高度平衡的二叉搜索树。
def sorted_array_to_bst(nums):
def helper(left, right):
if left > right:
return None
mid = (left + right) // 2
node = TreeNode(nums[mid])
node.left = helper(left, mid - 1)
node.right = helper(mid + 1, right)
return node
return helper(0, len(nums) - 1)
给定有序数组[-10,-3,0,5,9],构建一颗平衡二叉搜索树。
N 叉树是指每个节点有零个或多个子节点的树。实现 N 叉树的遍历。
class Node:
def __init__(self, val=None, children=[]):
self.val = val
self.children = children
def pre_order(root):
if not root:
return []
stack, res = [root], []
while stack:
node = stack.pop()
res.append(node.val)
stack += node.children[::-1]
return res
def post_order(root):
if not root:
return []
stack1, stack2 = [root], []
while stack1:
node = stack1.pop()
stack2.append(node.val)
stack1 += node.children
return stack2[::-1]
def level_order(root):
if not root:
return []
queue, res = [root], []
while queue:
level = []
for _ in range(len(queue)):
node = queue.pop(0)
level.append(node.val)
queue += node.children
res.append(level)
return res
给定 N 叉树[1,None,3,2,4,None,5,6],执行先序遍历、后序遍历和层序遍历,分别得到结果[1,3,5,6,2,4]、[5,6,3,2,4,1]和[[1], [3,2,4], [5,6]]