二叉树hot100-中等
1. 验证二叉搜索树 (Valid Binary Search Tree)
题目描述:
给定一个二叉树,判断它是否是一个有效的二叉搜索树。
一个有效的二叉搜索树定义如下:
-
节点的左子树只包含小于当前节点的数。
-
节点的右子树只包含大于当前节点的数。
-
所有左子树和右子树必须是二叉搜索树。
输入:
[5,1,4,null,null,3,6]
输出:
false
minval = float('-inf')maxval = float('inf')def BST(node,low,high):if not node:return Trueif not(low < node.val <high):return Falseleft = BST(node.left,low,node.val)right = BST(node.right,node.val,high)return left and rightreturn BST(root,minval,maxval)
2. 二叉搜索树中第 K 小的元素 (Kth Smallest Element in a BST)
题目描述:
给定一棵二叉搜索树,返回其中第 K 小的元素。
输入:
root = [3,1,4,null,2], k = 1
输出:
1
# 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
class Solution:def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:# 中序遍历 左中右self.res = []def inorder(node):if not node:return Noneinorder(node.left)self.res.append(node.val)inorder(node.right)return self.resout = inorder(root)return out[k-1]
3. 二叉树的右视图 (Binary Tree Right Side View)
题目描述:
给定一个二叉树,想象从右侧看到的树的节点值。返回从右侧看到的节点值。
输入:
[1,2,3,null,5,null,4]
输出:
[1, 3, 4]
# 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
class Solution:def rightSideView(self, root: Optional[TreeNode]) -> List[int]:# 层序遍历 append最后一个if not root:return []res = []queue = collections.deque([root])while queue:size = len(queue)for i in range(size):node = queue.popleft()if node.left:queue.append(node.left)if node.right:queue.append(node.right)if i == size-1:res.append(node.val)return res
4. 二叉树展开为链表 (Flatten Binary Tree to Linked List)
题目描述:
给定一个二叉树,将其展开为一个“单链表”形式,即将树的所有节点按先序遍历的顺序展开为一个链表。
输入:
[1,2,5,3,4,null,6]
输出:
1\2\5\3\4\6
class Solution:def flatten(self, root: Optional[TreeNode]) -> None:"""Do not return anything, modify root in-place instead."""self.res = []def preorder(node):if not node:return Noneself.res.append(node)preorder(node.left)preorder(node.right)preorder(root)for i in range(1,len(self.res)):prev,cur = self.res[i-1],self.res[i]prev.left = Noneprev.right = cur
5. 从前序与中序遍历序列构造二叉树 (Construct Binary Tree from Preorder and Inorder Traversal)
题目描述:
给定前序遍历和中序遍历的结果,构造出对应的二叉树。
输入:
preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出:
[3,9,20,null,null,15,7]
# 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
class Solution:def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:if not preorder or not inorder:return Nonemid = inorder.index(preorder[0])root = TreeNode(preorder[0])root.left = self.buildTree(preorder[1:mid+1],inorder[:mid])root.right = self.buildTree(preorder[mid+1:],inorder[mid+1:])return root
6. 路径总和 III (Path Sum III)
题目描述:
给定一个二叉树和一个目标和,找出所有从根节点到叶子节点的路径之和等于目标和的路径。
输入:
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
输出:
3
class Solution:def pathSum(self, root: Optional[TreeNode], targetSum: int) -> int:def countpath(node,targetSum): #统计当前节点向下的路径数if not node:return 0res = 0if node.val == targetSum:res += 1res += countpath(node.left,targetSum-node.val)res += countpath(node.right,targetSum-node.val)return resif not root:return 0return countpath(root,targetSum)+self.pathSum(root.left,targetSum)+self.pathSum(root.right,targetSum)
7. 二叉树的最近公共祖先 (Lowest Common Ancestor of a Binary Tree)
题目描述:
给定二叉树的根节点和两个节点,找出这两个节点的最近公共祖先。
输入:
root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:
3
关键点:我们要在树里「搜索」两个点 p
和 q
。
分为三种情况:
1、p q 一左一右 则root是
2、p是q的父亲
3、q是p父亲
递归三部曲:
第 1 步:定义递归函数
dfs(node)
返回:
-
如果在
node
这棵子树里找到了p
或q
,就返回对应节点。 -
如果没找到,返回
None
。 -
如果左右子树都找到了,返回当前节点(说明它是最近公共祖先)。
第 2 步:递归出口
-
如果
node is None
→ 返回None
-
如果
node == p or node == q
→ 返回node
(说明找到了目标)
第 3 步:单层逻辑
递归左右子树:
left = dfs(node.left) right = dfs(node.right)
-
如果
left
和right
都不是空 → 说明p
、q
分居左右 → 当前节点就是 LCA -
如果只有
left
不空 → 把left
往上传 -
如果只有
right
不空 → 把right
往上传
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':if not root or root == p or root == q:return rootleft = self.lowestCommonAncestor(root.left,p,q)right = self.lowestCommonAncestor(root.right,p,q)if left and right:return rootif not left:return rightif not right:return left
关键点:我们要在树里「搜索」两个点
p
和q
。代码里的root实际时node
8. 二叉树中的最大路径和 (Binary Tree Maximum Path Sum)
题目描述:
给定一个非空二叉树,返回其最大路径和。
输入:
root = [1,2,3]
输出:
6
class Solution:def maxPathSum(self, root: Optional[TreeNode]) -> int:self.res = float('-inf')def maxgain(node):if not node:return 0left = max(maxgain(node.left),0)right = max(maxgain(node.right),0)cur_gain = node.val + left + rightself.res = max(self.res,cur_gain)return node.val + max(left,right)maxgain(root)return self.res