【如果笔记对你有帮助,欢迎关注&点赞&收藏,收到正反馈会加快更新!谢谢支持!】
ps:笔记和代码按本人理解整理,重思路
题目43:验证二叉搜索树
- 题意:判断其是否是一个有效的二叉搜索树
- 关键:
- 二叉搜索树特性 “左子树所有节点 < 当前节点 < 右子树所有节点”
- 二叉搜索树的中序遍历得到的结果是有序(递增)【只要满足这个条件就是二叉搜索树】
- 拆解:
「代码逻辑」 pre:前一个节点值 验证二叉搜索树(root) 如果root为None:True 1. 验证二叉搜索树(左子树) -> True/False 2. 【处理中间节点】 当前节点和pre比较:-> True/False pre <- 当前节点 3. 验证二叉搜索树(右子树) -> True/False 注:1 & 2 & 3 都为True才可以(如果1为False,2也不用进行) - 代码:
class Solution: pre = -inf def isValidBST(self, root: Optional[TreeNode]) -> bool: if not root: return True # 不满足条件的情况,直接返回False;先遍历left(按照中序遍历顺序) if not self.isValidBST(root.left) or root.val <= self.pre: return False self.pre = root.val # 更新self.pre return self.isValidBST(root.right)
题目44: 二叉搜索树中第 K 小的元素
230. 二叉搜索树中第 K 小的元素 - 力扣(LeetCode)
- 关键:和题目43同理,利用二叉搜索树中序遍历的有序性
- 代码:
class Solution: def kthSmallest(self, root: Optional[TreeNode], k: int) -> int: count = 0 result = None def dfs(root): if not root: return dfs(root.left) nonlocal count, result count += 1 if count == k: result = root.val dfs(root.right) dfs(root) return result
题目45:二叉树的右视图
- 题意:找到二叉树每层最右边的节点

- 直接方法:同 题目41:二叉树的层序遍历
- 递归方法:先遍历左子树再遍历右子树 → 同样深度后遍历(右)的覆盖先遍历(左)
class Solution: def rightSideView(self, root: Optional[TreeNode]) -> List[int]: result = [] def dfs(root, height): if not root: return if height >= len(result): # 第一次遇到当前深度 result.append(root.val) else: # 覆盖同样深度左侧的节点 result[height] = root.val dfs(root.left, height+1) dfs(root.right, height+1) dfs(root, 0) return result
题目46:二叉树展开为链表
- 题意:将二叉树展成链表(并到右侧),按“先序遍历”排序

- 关键:用栈stack以“先右后左”的顺序存节点 → 取出时“先左后右”
- 代码:
class Solution: def flatten(self, root: Optional[TreeNode]) -> None: """ Do not return anything, modify root in-place instead. """ if not root: return None stack = [root] prev = None while stack: node = stack.pop() if node.right: stack.append(node.right) if node.left: stack.append(node.left) if prev: prev.right = node prev.left = None prev = node return root
题目47:从前序与中序遍历序列构造二叉树
105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)
- 题意:用二叉树的前序遍历和中序遍历,构造二叉树

- 关键:root = 前序遍历第一个,左子树 = 中序遍历的root左侧,右子树 = 中序遍历的root右侧
- 代码:
class Solution: def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: if not preorder: return None left_size = inorder.index(preorder[0]) left = self.buildTree(preorder[1: 1+left_size], inorder[:left_size]) right = self.buildTree(preorder[1+left_size:], inorder[1+left_size:]) return TreeNode(preorder[0], left, right)
题目48:路径总和 III
- 题意:找到满足目标和的二叉树的路径(自上而下的任意一段)

- 关键:哈希表记录前缀和
- 拆解:
「代码逻辑」 # 自上而下传递 prefix:哈希表记录前缀和 {前缀和:数量} 路径总和(root, 之前的路径和): - 更新路径和 = 之前的路径和 + 当前值 - 更新结果:+(新路径和-前缀和==target)的数量 - 更新哈希表:{新路径和: 数量+1} - 路径总和(root.left, 新路径和) - 路径总和(root.right, 新路径和) - 代码:
class Solution: def pathSum(self, root: Optional[TreeNode], targetSum: int) -> int: ans = 0 prefix = defaultdict(int) prefix[0] = 1 def dfs(root, s): if not root: return nonlocal ans s += root.val ans += prefix[s - targetSum] prefix[s] += 1 dfs(root.left, s) dfs(root.right, s) prefix[s] -= 1 dfs(root, 0) return ans
题目49: 二叉树的最近公共祖先
236. 二叉树的最近公共祖先 - 力扣(LeetCode)
- 最近公共祖先:对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)

- 关键:自下而上传递

- 代码:
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 elif left: return left elif right: return right
题目50: 二叉树中的最大路径和
124. 二叉树中的最大路径和 - 力扣(LeetCode)
- 题意:找到二叉树中和最大的路径(不限制方向)

- 关键:动态规划;自下而上传递
- 总路径 = top1长的子节点路径【左边的深度】 → 当前节点 → top2长的子节点路径【右边的深度】
- 因为路径和可为负,所以最大值不一定是整段路径
- 拆解:
「代码逻辑」 # 自下而上传递 找最大路径和(root): - 左路径 = 找最大路径和(root.left) - 右路径 = 找最大路径和(root.right) - 更新结果 max(1.左中右 2.左中 3.右中 4.中) - return max(左中,右中,中)#需要自下而上一个方向的路径 - 代码:
class Solution: def maxPathSum(self, root: Optional[TreeNode]) -> int: result = float('-inf') def searchPath(root): if not root: return 0 left = searchPath(root.left) right = searchPath(root.right) nonlocal result result = max(result, left+root.val+right, left+root.val, root.val+right, root.val) return max(left, right, 0) + root.val searchPath(root) return result


9万+

被折叠的 条评论
为什么被折叠?



