二叉树 144. 二叉树的前序遍历 给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
示例 1:
**输入:**root = [1,null,2,3]
输出: [1,2,3]
解释:
示例 2:
**输入:**root = [1,2,3,4,5,null,8,null,null,6,7,9]
输出: [1,2,4,5,6,7,3,8,9]
解释:
示例 3:
**输入:**root = []
输出: []
示例 4:
**输入:**root = [1]
输出: [1]
提示:
树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100
**进阶:**递归算法很简单,你可以通过迭代算法完成吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from collections import dequeclass Solution : def preorderTraversal (self, root: Optional [TreeNode] ) -> List [int ]: stack = [root] if root is not None else [] ans = [] while len (stack)>0 : node = stack.pop() ans.append(node.val) if node.right is not None : stack.append(node.right) if node.left is not None : stack.append(node.left) return ans
145. 二叉树的后序遍历 给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。
示例 1:
**输入:**root = [1,null,2,3]
输出: [3,2,1]
解释:
示例 2:
**输入:**root = [1,2,3,4,5,null,8,null,null,6,7,9]
输出: [4,6,7,5,2,9,8,3,1]
解释:
示例 3:
**输入:**root = []
输出: []
示例 4:
**输入:**root = [1]
输出: [1]
提示:
树中节点的数目在范围 [0, 100] 内
-100 <= Node.val <= 100
**进阶:**递归算法很简单,你可以通过迭代算法完成吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution : def postorderTraversal (self, root: Optional [TreeNode] ) -> List [int ]: stack = [root] if root is not None else [] ans = [] while len (stack) > 0 : node = stack.pop() if node is not None : stack.append(node) stack.append(None ) if node.right is not None : stack.append(node.right) if node.left is not None : stack.append(node.left) else : node = stack.pop() ans.append(node.val) return ans
94. 二叉树的中序遍历 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
示例 1:
1 2 输入:root = [1,null,2,3] 输出:[1,3,2]
示例 2:
示例 3:
提示:
树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution : def inorderTraversal (self, root: Optional [TreeNode] ) -> List [int ]: if root is None : return [] stack = [(root, False )] res = [] while stack: item = stack.pop() if not item[1 ]: stack.append((item[0 ], True )) if item[0 ].left is not None : stack.append((item[0 ].left, False )) else : res.append(item[0 ].val) if item[0 ].right is not None : stack.append((item[0 ].right, False )) return res
102. 二叉树的层序遍历 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:
1 2 输入:root = [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]]
示例 2:
示例 3:
提示:
树中节点数目在范围 [0, 2000] 内
-1000 <= Node.val <= 1000
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution : def levelOrder (self, root: Optional [TreeNode] ) -> List [List [int ]]: from collections import deque if root is None : return [] res = [] queue = deque([root]) layer = 0 while len (queue): layerlist = [] for _ in range (len (queue)): node = queue.popleft() layerlist.append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) layer += 1 res.append(layerlist) return res
226. 翻转二叉树 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
示例 1:
1 2 输入:root = [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]
示例 2:
1 2 输入:root = [2,1,3] 输出:[2,3,1]
示例 3:
提示:
树中节点数目范围在 [0, 100] 内
-100 <= Node.val <= 100
1 2 3 4 5 6 7 8 9 10 11 12 class Solution : def invertTree (self, root: Optional [TreeNode] ) -> Optional [TreeNode]: if root is None : return root root.right, root.left = self .invertTree(root.left), self .invertTree(root.right) return root
101. 对称二叉树 给你一个二叉树的根节点 root , 检查它是否轴对称。
示例 1:
1 2 输入:root = [1,2,2,3,4,4,3] 输出:true
示例 2:
1 2 输入:root = [1,2,2,null,3,null,3] 输出:false
提示:
树中节点数目在范围 [1, 1000] 内
-100 <= Node.val <= 100
**进阶:**你可以运用递归和迭代两种方法解决这个问题吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 def isSameTree (a, b ): if a is None or b is None : return a is b return a.val == b.val and isSameTree(a.left, b.left) and isSameTree(a.right, b.right) TreeNode.__eq__ = isSameTree class Solution : def isSymmetric (self, root: Optional [TreeNode] ) -> bool : def reverse (root ): if root is None : return None root.left, root.right = reverse(root.right), reverse(root.left) return root return root.left == reverse(root.right)
104. 二叉树的最大深度 给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
示例 1:
1 2 输入:root = [3,9,20,null,null,15,7] 输出:3
示例 2:
1 2 输入:root = [1,null,2] 输出:2
提示:
树中节点的数量在 [0, 104] 区间内。
-100 <= Node.val <= 100
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution : def maxDepth (self, root: Optional [TreeNode] ) -> int : return self .dfs(root) def dfs (self, root ): if root is None : return 0 else : return max (self .dfs(root.left), self .dfs(root.right)) + 1
111. 二叉树的最小深度 给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
**说明:**叶子节点是指没有子节点的节点。
示例 1:
1 2 输入:root = [3,9,20,null,null,15,7] 输出:2
示例 2:
1 2 输入:root = [2,null,3,null,4,null,5,null,6] 输出:5
提示:
树中节点数的范围在 [0, 105] 内
-1000 <= Node.val <= 1000
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution : def getDepth (self, node ): if node is None : return 0 leftDepth = self .getDepth(node.left) rightDepth = self .getDepth(node.right) if node.left is None and node.right is not None : return 1 + rightDepth if node.left is not None and node.right is None : return 1 + leftDepth result = 1 + min (leftDepth, rightDepth) return result def minDepth (self, root ): return self .getDepth(root)
222. 完全二叉树的节点个数 给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(从第 0 层开始),则该层包含 1~ 2h 个节点。
示例 1:
1 2 输入:root = [1,2,3,4,5,6] 输出:6
示例 2:
示例 3:
提示:
树中节点的数目范围是[0, 5 * 104]
0 <= Node.val <= 5 * 104
题目数据保证输入的树是 完全二叉树
**进阶:**遍历树来统计节点是一种时间复杂度为 O(n) 的简单解决方案。你可以设计一个更快的算法吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution : def countNodes (self, root: Optional [TreeNode] ) -> int : def height (root ): p = root if p is None : return 0 height = 0 while p is not None : p=p.left height+=1 return height def nodeNums (root ): if root is None : return 0 if height(root.left) == height(root.right): return 2 **height(root.left) -1 + nodeNums(root.right) + 1 else : return 2 **(height(root.right)) -1 +nodeNums(root.left) +1 print (height(root)) return nodeNums(root)
110. 平衡二叉树 给定一个二叉树,判断它是否是 平衡二叉树
示例 1:
1 2 输入:root = [3,9,20,null,null,15,7] 输出:true
示例 2:
1 2 输入:root = [1,2,2,3,3,null,null,4,4] 输出:false
示例 3:
提示:
树中的节点数在范围 [0, 5000] 内
-104 <= Node.val <= 104
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution : def isBalanced (self, root: Optional [TreeNode] ) -> bool : def maxDepth (root ): if root is None : return 0 else : leftdepth = maxDepth(root.left) rightdepth = maxDepth(root.right) return 1 + max (leftdepth, rightdepth) if root is None : return True else : if abs (maxDepth(root.left)-maxDepth(root.right)) > 1 : return False else : return self .isBalanced(root.left) and self .isBalanced(root.right)
257. 二叉树的所有路径 给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。
示例 1:
1 2 输入:root = [1,2,3,null,5] 输出:["1->2->5","1->3"]
示例 2:
提示:
树中节点的数目在范围 [1, 100] 内
-100 <= Node.val <= 100
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution : def binaryTreePaths (self, root: Optional [TreeNode] ) -> List [str ]: strPattern = [] reslist = [] def recur (node ): strPattern.append(str (node.val)) if node.left is None and node.right is None : reslist.append('->' .join(strPattern)) if node.left is not None : recur(node.left) if node.right is not None : recur(node.right) strPattern.pop() recur(root) return reslist
404. 左叶子之和 给定二叉树的根节点 root ,返回所有左叶子之和。
示例 1:
1 2 3 输入: root = [3,9,20,null,null,15,7] 输出: 24 解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24
示例 2:
提示:
节点数在 [1, 1000] 范围内
-1000 <= Node.val <= 1000
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution : def sumOfLeftLeaves (self, root: Optional [TreeNode] ) -> int : self .sumNums = 0 def leftSumFlag (root, isLeft ): if root is None : return if root.left is None and root.right is None and isLeft: self .sumNums += root.val else : leftSumFlag(root.left, isLeft = True ) leftSumFlag(root.right, isLeft = False ) leftSumFlag(root, isLeft = False ) return self .sumNums
513. 找树左下角的值 给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
示例 1:
1 2 输入: root = [2,1,3] 输出: 1
示例 2:
1 2 输入: [1,2,3,4,null,5,6,null,null,7] 输出: 7
提示:
二叉树的节点个数的范围是 [1,104]
-231 <= Node.val <= 231 - 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution : def findBottomLeftValue (self, root: Optional [TreeNode] ) -> int : self .max_depth = 0 self .nowNum = None def recur (root, depth ): if root.left is None and root.right is None : if depth > self .max_depth: self .nowNum = root.val self .max_depth = depth else : if root.left is not None : recur(root.left, depth + 1 ) if root.right is not None : recur(root.right, depth + 1 ) recur(root, 1 ) return self .nowNum
112. 路径总和 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
叶子节点 是指没有子节点的节点。
示例 1:
1 2 3 输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22 输出:true 解释:等于目标和的根节点到叶节点路径如上图所示。
示例 2:
1 2 3 4 5 6 输入:root = [1,2,3], targetSum = 5 输出:false 解释:树中存在两条根节点到叶子节点的路径: (1 --> 2): 和为 3 (1 --> 3): 和为 4 不存在 sum = 5 的根节点到叶子节点的路径。
示例 3:
1 2 3 输入:root = [], targetSum = 0 输出:false 解释:由于树是空的,所以不存在根节点到叶子节点的路径。
提示:
树中节点的数目在范围 [0, 5000] 内
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution : def hasPathSum (self, root: Optional [TreeNode], targetSum: int ) -> bool : def recur (root, sumNum ): if root is None : return False nonlocal targetSum if root.left is None and root.right is None : if sumNum + root.val == targetSum: return True return recur(root.left, sumNum + root.val) or recur(root.right, sumNum + root.val) return recur(root, 0 )
113. 路径总和 II 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
示例 1:
1 2 输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22 输出:[[5,4,11,2],[5,8,4,5]]
示例 2:
1 2 输入:root = [1,2,3], targetSum = 5 输出:[]
示例 3:
1 2 输入:root = [1,2], targetSum = 0 输出:[]
提示:
树中节点总数在范围 [0, 5000] 内
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
106. 从中序与后序遍历序列构造二叉树 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
示例 1:
1 2 输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3] 输出:[3,9,20,null,null,15,7]
示例 2:
1 2 输入:inorder = [-1], postorder = [-1] 输出:[-1]
提示:
1 <= inorder.length <= 3000
postorder.length == inorder.length
-3000 <= inorder[i], postorder[i] <= 3000
inorder 和 postorder 都由 不同 的值组成
postorder 中每一个值都在 inorder 中
inorder 保证 是树的中序遍历
postorder 保证 是树的后序遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution : def buildTree (self, inorder: List [int ], postorder: List [int ] ) -> Optional [TreeNode]: if len (postorder) == 0 : return None rootVal = postorder.pop() inOrderSplitIndex = inorder.index(rootVal) leftInorder = inorder[:inOrderSplitIndex] rightInorder = inorder[inOrderSplitIndex+1 :] leftPostorder = postorder[:len (leftInorder)] rightPostorder = postorder[len (leftInorder):] return TreeNode(val = rootVal, left = self .buildTree(leftInorder, leftPostorder), right = self .buildTree(rightInorder, rightPostorder))
654. 最大二叉树 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:
创建一个根节点,其值为 nums 中的最大值。
递归地在最大值 左边 的 子数组前缀上 构建左子树。
递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums 构建的 最大二叉树 。
示例 1:
1 2 3 4 5 6 7 8 9 10 11 12 输入:nums = [3,2,1,6,0,5] 输出:[6,3,5,null,2,0,null,null,1] 解释:递归调用如下所示: - [3,2,1,6,0,5] 中的最大值是 6 ,左边部分是 [3,2,1] ,右边部分是 [0,5] 。 - [3,2,1] 中的最大值是 3 ,左边部分是 [] ,右边部分是 [2,1] 。 - 空数组,无子节点。 - [2,1] 中的最大值是 2 ,左边部分是 [] ,右边部分是 [1] 。 - 空数组,无子节点。 - 只有一个元素,所以子节点是一个值为 1 的节点。 - [0,5] 中的最大值是 5 ,左边部分是 [0] ,右边部分是 [] 。 - 只有一个元素,所以子节点是一个值为 0 的节点。 - 空数组,无子节点。
示例 2:
1 2 输入:nums = [3,2,1] 输出:[3,null,2,null,1]
提示:
1 <= nums.length <= 1000
0 <= nums[i] <= 1000
nums 中的所有整数 互不相同
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution : def constructMaximumBinaryTree (self, nums: List [int ] ) -> Optional [TreeNode]: if len (nums) == 0 : return None else : idx = nums.index(max (nums)) return TreeNode(val=nums[idx], left = self .constructMaximumBinaryTree(nums[:idx]), right = self .constructMaximumBinaryTree(nums[idx+1 :]))
617. 合并二叉树 给你两棵二叉树: root1 和 root2 。
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。
示例 1:
1 2 输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7] 输出:[3,4,5,5,4,null,7]
示例 2:
1 2 输入:root1 = [1], root2 = [1,2] 输出:[2,2]
提示:
两棵树中的节点数目在范围 [0, 2000] 内
-104 <= Node.val <= 104
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution : def mergeTrees (self, root1: Optional [TreeNode], root2: Optional [TreeNode] ) -> Optional [TreeNode]: if root1 is None and root2 is None : return None elif root1 is not None and root2 is None : node = TreeNode(val = root1.val) elif root1 is None and root2 is not None : node = TreeNode(val = root2.val) else : node = TreeNode(val = root1.val + root2.val) node.left = self .mergeTrees(root1.left if root1 is not None else None , root2.left if root2 is not None else None ) node.right = self .mergeTrees(root1.right if root1 is not None else None , root2.right if root2 is not None else None ) return node
700. 二叉搜索树中的搜索 给定二叉搜索树(BST)的根节点 root 和一个整数值 val。
你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。
示例 1:
1 2 输入:root = [4,2,7,1,3], val = 2 输出:[2,1,3]
示例 2:
1 2 输入:root = [4,2,7,1,3], val = 5 输出:[]
提示:
树中节点数在 [1, 5000] 范围内
1 <= Node.val <= 107
root 是二叉搜索树
1 <= val <= 107
1 2 3 4 5 6 7 8 9 class Solution : def searchBST (self, root: Optional [TreeNode], val: int ) -> Optional [TreeNode]: return root if root is None or val == root.val else self .searchBST(root.left if val < root.val else root.right, val)
98. 验证二叉搜索树 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
节点的左子树只包含严格小于 当前节点的数。
节点的右子树只包含 严格大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
1 2 输入:root = [2,1,3] 输出:true
示例 2:
1 2 3 输入:root = [5,1,4,null,null,3,6] 输出:false 解释:根节点的值是 5 ,但是右子节点的值是 4 。
提示:
树中节点数目范围在[1, 104] 内
-231 <= Node.val <= 231 - 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution : def isValidBST (self, root: Optional [TreeNode] ) -> bool : def dfs (root, Nrange ): if root is None : return True if not Nrange[0 ] < root.val < Nrange[1 ]: return False else : left, right = True , True if root.left is not None : left = dfs(root.left, [Nrange[0 ], root.val]) if root.right is not None : right = dfs(root.right, [root.val, Nrange[1 ]]) return left and right return dfs(root, [-inf, inf])
530. 二叉搜索树的最小绝对差 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。
示例 1:
1 2 输入:root = [4,2,6,1,3] 输出:1
示例 2:
1 2 输入:root = [1,0,48,null,null,12,49] 输出:1
提示:
树中节点的数目范围是 [2, 104]
0 <= Node.val <= 105
**注意:**本题与 783 https://leetcode.cn/problems/minimum-distance-between-bst-nodes/ 相同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution : def getMinimumDifference (self, root: Optional [TreeNode] ) -> int : last = None minD = inf def getMinD (root ): nonlocal minD, last if root is None : return else : getMinD(root.left) if last is None : last = root.val else : if abs (root.val-last) < minD: minD = abs (root.val-last) last = root.val getMinD(root.right) getMinD(root) return minD
501. 二叉搜索树中的众数 给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数 (即,出现频率最高的元素)。
如果树中有不止一个众数,可以按 任意顺序 返回。
假定 BST 满足如下定义:
结点左子树中所含节点的值 小于等于 当前节点的值
结点右子树中所含节点的值 大于等于 当前节点的值
左子树和右子树都是二叉搜索树
示例 1:
1 2 输入:root = [1,null,2,2] 输出:[2]
示例 2:
提示:
树中节点的数目在范围 [1, 104] 内
-105 <= Node.val <= 105
**进阶:**你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class Solution : def findMode (self, root: Optional [TreeNode] ) -> List [int ]: ansList = [] maxTimes = 0 nowTimes = 0 nowNum = None def midRecur (root ): nonlocal maxTimes, nowNum, nowTimes, ansList if root is None : return else : midRecur(root.left) if root.val == nowNum: nowTimes +=1 else : nowNum = root.val nowTimes = 1 if nowTimes == maxTimes: ansList.append(root.val) if nowTimes > maxTimes: maxTimes = nowTimes ansList = [root.val] midRecur(root.right) midRecur(root) return ansList
236. 二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科 中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先 )。”
示例 1:
1 2 3 输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 输出:3 解释:节点 5 和节点 1 的最近公共祖先是节点 3 。
示例 2:
1 2 3 输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出:5 解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。
示例 3:
1 2 输入:root = [1,2], p = 1, q = 2 输出:1
提示:
树中节点数目在范围 [2, 105] 内。
-109 <= Node.val <= 109
所有 Node.val 互不相同 。
p != q
p 和 q 均存在于给定的二叉树中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution : def lowestCommonAncestor (self, root: 'TreeNode' , p: 'TreeNode' , q: 'TreeNode' ) -> 'TreeNode' : def dfs (root, p, q ): if root is None : return None if root == q: return q if root == p: return p l = dfs(root.left, p, q) r = dfs(root.right, p, q) if l and r: return root else : return l or r return dfs(root, p, q)
235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科 中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先 )。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
示例 1:
1 2 3 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 输出: 6 解释: 节点 2 和节点 8 的最近公共祖先是 6。
示例 2:
1 2 3 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4 输出: 2 解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
说明:
所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉搜索树中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution : def lowestCommonAncestor (self, root: 'TreeNode' , p: 'TreeNode' , q: 'TreeNode' ) -> 'TreeNode' : if root is None : return None if (p.val > root.val and q.val < root.val) or (p.val < root.val and q.val > root.val) or (p.val == root.val) or (q.val == root.val): return root elif p.val > root.val and q.val > root.val: return self .lowestCommonAncestor(root.right, p, q) else : return self .lowestCommonAncestor(root.left,p, q)
701. 二叉搜索树中的插入操作 给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。
注意 ,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果 。
示例 1:
1 2 3 输入:root = [4,2,7,1,3], val = 5 输出:[4,2,7,1,3,5] 解释:另一个满足题目要求可以通过的树是:
示例 2:
1 2 输入:root = [40,20,60,10,30,50,70], val = 25 输出:[40,20,60,10,30,50,70,null,null,25]
示例 3:
1 2 输入:root = [4,2,7,1,3,null,null,null,null,null,null], val = 5 输出:[4,2,7,1,3,5]
提示:
树中的节点数将在 [0, 104]的范围内。
-108 <= Node.val <= 108
所有值 Node.val 是 独一无二 的。
-108 <= val <= 108
保证 val 在原始BST中不存在。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution : def insertIntoBST (self, root: Optional [TreeNode], val: int ) -> Optional [TreeNode]: if root is None : return TreeNode(val = val) if val < root.val: if root.left is None : root.left = TreeNode(val = val) return root else : self .insertIntoBST(root.left, val) elif val > root.val: if root.right is None : root.right = TreeNode(val = val) return root else : self .insertIntoBST(root.right, val) return root
450. 删除二叉搜索树中的节点 给定一个二叉搜索树的根节点 root 和一个值 key ,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:
首先找到需要删除的节点;
如果找到了,删除它。
示例 1:
1 2 3 4 5 输入:root = [5,3,6,2,4,null,7], key = 3 输出:[5,4,6,2,null,null,7] 解释:给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。 一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。 另一个正确答案是 [5,2,6,null,4,null,7]。
示例 2:
1 2 3 输入: root = [5,3,6,2,4,null,7], key = 0 输出: [5,3,6,2,4,null,7] 解释: 二叉树不包含值为 0 的节点
示例 3:
1 2 输入: root = [], key = 0 输出: []
提示:
节点数的范围 [0, 104].
-105 <= Node.val <= 105
节点值唯一
root 是合法的二叉搜索树
-105 <= key <= 105
进阶: 要求算法时间复杂度为 O(h),h 为树的高度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution : def deleteNode (self, root: Optional [TreeNode], key: int ) -> Optional [TreeNode]: if root is None : return None if root.val < key: root.right = self .deleteNode(root.right, key) elif root.val > key: root.left = self .deleteNode(root.left, key) else : if root.left is None : return root.right elif root.right is None : return root.left else : p = root.left while p.right is not None : p = p.right p.right = root.right return root.left return root
108. 将有序数组转换为二叉搜索树 给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 平衡 二叉搜索树。
示例 1:
1 2 3 输入:nums = [-10,-3,0,5,9] 输出:[0,-3,9,-10,null,5] 解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:
示例 2:
1 2 3 输入:nums = [1,3] 输出:[3,1] 解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 按 严格递增 顺序排列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution : def sortedArrayToBST (self, nums: List [int ] ) -> Optional [TreeNode]: if len (nums) ==0 : return None midNum = len (nums) // 2 midNode = TreeNode(nums[midNum]) midNode.left = self .sortedArrayToBST(nums[:midNum]) midNode.right = self .sortedArrayToBST(nums[midNum+1 :]) return midNode
538. 把二叉搜索树转换为累加树 给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
提醒一下,二叉搜索树满足下列约束条件:
节点的左子树仅包含键 小于 节点键的节点。
节点的右子树仅包含键 大于 节点键的节点。
左右子树也必须是二叉搜索树。
**注意:**本题和 1038: https://leetcode.cn/problems/binary-search-tree-to-greater-sum-tree/ 相同
示例 1:
1 2 输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8] 输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
示例 2:
1 2 输入:root = [0,null,1] 输出:[1,null,1]
示例 3:
1 2 输入:root = [1,0,2] 输出:[3,3,2]
示例 4:
1 2 输入:root = [3,2,4,1] 输出:[7,9,4,10]
提示:
树中的节点数介于 0 和 104之间。
每个节点的值介于 -104 和 104 之间。
树中的所有值 互不相同 。
给定的树为二叉搜索树。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution : def convertBST (self, root: Optional [TreeNode] ) -> Optional [TreeNode]: self .dfs(root, 0 ) return root def dfs (self, root, last_sum ): if root is None : return last_sum rootSum = self .dfs(root.right, last_sum) root.val = rootSum + root.val returnSum = self .dfs(root.left, root.val) return returnSum