“抱佛脚”系列(代码部分); 所有代码均基于 Python3;
记号LC{xx}
表示 Leetcode 第 xx 题,例如LC20
表示 Leetcode 第 20题。
# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
中序遍历的顺序:左-根-右 (left - root - right)
# 给定一个二叉树的根节点 root ,返回它的 中序 遍历。
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
if root is None:
return []
return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)
# 给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
if root is None:
return []
return [root.val] + self.preorderTraversal(root.left) + self.preorderTraversal(root.right)
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if root is None:
return []
res = []
nodes_next = [root]
while len(nodes_next):
res.append([nd.val for nd in nodes_next])
tmp = []
for node in nodes_next:
if node.left: tmp.append(node.left)
if node.right: tmp.append(node.right)
nodes_next = tmp
return res
链接:https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
if len(nums) <= 0:
return
elif len(nums) <= 1:
return TreeNode(val = nums[0])
mid = len(nums) // 2
root = TreeNode(
val = nums[mid],
left = self.sortedArrayToBST(nums[: mid]),
right = self.sortedArrayToBST(nums[mid + 1: ])
)
return root
链接:https://leetcode-cn.com/problems/validate-binary-search-tree
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
一个二叉搜索树具有如下特征:
⚠️要点
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
return self._is_valid(root)
def _is_valid(self, root, vmin=-float("inf"), vmax=float("inf")):
if root is None:
return True
if (root.val > vmin) and (root.val < vmax):
return self._is_valid(root.left, vmin, root.val) and self._is_valid(root.right, root.val, vmax)
return False
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
根据一棵树的前序遍历与中序遍历构造二叉树。
注意: 你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
if not len(preorder): return None
root_val = preorder[0]
root_loc = inorder.index(root_val) # 左数第一个匹配元素的下标
return TreeNode(
root_val,
left = self.buildTree(preorder[1: root_loc + 1], inorder[: root_loc]),
right = self.buildTree(preorder[root_loc + 1: ], inorder[root_loc + 1: ])
)
(腾讯 面试题)
二叉树中每个节点有个分数,从中选择一些节点并返回它们的累加分数的最大值。规则:如果选择某个节点,就不能再选择它相邻的(子)节点。
⚠️要点
def maxScore(node: TreeNode):
if node is None: return 0
v11, v12 = maxScore(node.left)
v21, v22 = maxScore(node.right)
v_exclude_root = v11 + v21
v_max = max(v12 + v22 + node.val, v_exclue_root)
return v_max, v_exlude_root
链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
最近公共祖先的定义为:
对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。
示例 2:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
# binary seaching tree
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if p.val < root.val > q.val:
return self.lowestCommonAncestor(root.left, p, q)
if p.val > root.val < q.val:
return self.lowestCommonAncestor(root.right, p, q)
return root
与上一题不同的是,对于一般二叉树,节点的数值没有相对大小限制。
⚠️要点
分别递归搜索左/右子树,寻找p或q,会出现三种情况:
# general binary tree
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if (root is None) or (root is p) or (root is q):
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if left and right:
return root
return right if left is None else left