输入:[2,2,2,5,2] 输出:false 提示: 给定树的节点数范围是 [1, 100]。 每个节点的值都是整数,范围为 [0, 99] 。 ''' from base import TreeNode class Solution: def isUnivalTree(self, root: TreeNode) -> bool: def _find_next(p): if not p: return True, None ls, lv = _find_next(p.left) rs, rv = _find_next(p.right) if ls and rs: if (lv is None or lv == p.val) and (rv is None or rv == p.val): return True, p.val return False, None status, val = _find_next(root) return status so = Solution() print(so.isUnivalTree(TreeNode.create_tree([1, 1, 1, 1, 1, None, 1])) == True) print(so.isUnivalTree(TreeNode.create_tree([2, 2, 2, 5, 2])) == False)
class Solution: def increasingBST(self, root: TreeNode) -> TreeNode: def _find_mid(p): if not p.left: if not p.right: return p, p r1, r2 = _find_mid(p.right) p.right = r1 return p, r2 l1, l2 = _find_mid(p.left) l2.right = p p.left = None if not p.right: return l1, p r1, r2 = _find_mid(p.right) p.right = r1 return l1, r2 root1, root2 = _find_mid(root) return root1 so = Solution() print( so.increasingBST( TreeNode.create_tree( [5, 3, 6, 2, 4, None, 8, 1, None, None, None, 7, 9])))
输出: 转换为累加树: 18 / \ 20 13 注意:本题和 1038: https://leetcode-cn.com/problems/binary-search-tree-to-greater-sum-tree/ 相同 ''' from base import TreeNode class Solution: def convertBST(self, root: TreeNode) -> TreeNode: # 根据特性,先右节点 self.sum = 0 def _get_count(p): if not p: return 0 _get_count(p.right) self.sum += p.val p.val = self.sum _get_count(p.left) return p _get_count(root) return root so = Solution() print(so.convertBST(TreeNode.create_tree([5, 2, 13]))) print(so.convertBST(TreeNode.create_tree([2, 0, 3, -4, 1])))
class Solution: def isSubtree(self, s: TreeNode, t: TreeNode) -> bool: # DFS def _check(ss, tt): if ss and tt: if ss.val == tt.val: return _check(ss.left, tt.left) and _check( ss.right, tt.right) else: return False elif not ss and not tt: return True else: return False def _find_next(ss, tt): if not ss: return False return _check(ss, tt) or _find_next(ss.left, tt) or _find_next( ss.right, tt) return _find_next(s, t) so = Solution() print( so.isSubtree(TreeNode.create_tree([3, 4, 5, 1, 2]), TreeNode.create_tree([4, 1, 2])) == True) print( so.isSubtree(TreeNode.create_tree([3, 4, 5, 1, 2, None, None, 0]), TreeNode.create_tree([4, 1, 2])) == True)
class Solution: def getMinimumDifference(self, root: TreeNode) -> int: # 根据搜索数据的特性,比较一个节点与其子节点的差最小,左子树的最右,右子树的最左 min_val = None # 层次遍历 before = [root] while before: after = [] for b in before: # 获取当前的左子树最大和右子树最小 if b.left: bleft = b.left while bleft.right: bleft = bleft.right min_val = abs(b.val - bleft.val) if min_val is None else min(min_val, abs(b.val - bleft.val)) if b.right: bright = b.right while bright.left: bright = bright.left min_val = abs(b.val - bright.val) if min_val is None else min(min_val, abs(b.val - bright.val)) if b.left: after.append(b.left) if b.right: after.append(b.right) before = after return min_val so = Solution() print(so.getMinimumDifference(TreeNode.create_tree([1, None, 3, 2])) == 1)
输出: "1(2()(4))(3)" 解释: 和第一个示例相似, 除了我们不能省略第一个对括号来中断输入和输出之间的一对一映射关系。 ''' from base import TreeNode class Solution: def tree2str(self, t: TreeNode) -> str: # 后序遍历 def _find_last(p): if not p: return "" left = _find_last(p.left) right = _find_last(p.right) if not left and not right: return str(p.val) elif right: return str(p.val) + "(%s)(%s)" % (left, right) else: return str(p.val) + "(%s)" % left result = _find_last(t) return result so = Solution() print(so.tree2str(TreeNode.create_tree([1, 2, 3, 4])) == "1(2(4))(3)") print(so.tree2str(TreeNode.create_tree([1, 2, 3, None, 4])) == "1(2()(4))(3)")
class Solution: def findTarget(self, root: TreeNode, k: int) -> bool: # 将搜索树整理成数组 record = [] def _get_list(p): if not p: return _get_list(p.left) record.append(p.val) _get_list(p.right) _get_list(root) # 使用双指针法 start = 0 end = len(record) - 1 while start < end: if record[start] + record[end] == k: return True elif record[start] + record[end] > k: end -= 1 else: start += 1 return False so = Solution() print(so.findTarget(TreeNode.create_tree([5, 3, 6, 2, 4, None, 7]), 9) == True) print( so.findTarget(TreeNode.create_tree([5, 3, 6, 2, 4, None, 7]), 28) == False)
注意: 合并必须从两个树的根节点开始。 ''' from base import TreeNode class Solution: def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode: def _find_first(p1, p2): p1.val += p2.val if p1.left and p2.left: _find_first(p1.left, p2.left) elif not p1.left and p2.left: p1.left = p2.left if p1.right and p2.right: _find_first(p1.right, p2.right) elif not p1.right and p2.right: p1.right = p2.right if not t1 and not t2: return t1 elif t1 and t2: _find_first(t1, t2) return t1 else: return t1 if t1 else t2 so = Solution() so.mergeTrees(TreeNode.create_tree())
if not p: return None, 0 left_val, left_length = _find_next(p.left) right_val, right_length = _find_next(p.right) if p.val == left_val and p.val == right_val: if left_length + right_length + 2 > self.max_length: self.max_length = left_length + right_length + 2 return p.val, max(left_length, right_length) + 1 elif p.val == left_val: if left_length + 1 > self.max_length: self.max_length = left_length + 1 return p.val, left_length + 1 elif p.val == right_val: if right_length + 1 > self.max_length: self.max_length = right_length + 1 return p.val, right_length + 1 else: return p.val, 0 _find_next(root) return self.max_length so = Solution() print( so.longestUnivaluePath(TreeNode.create_tree([5, 4, 5, 1, 1, None, 5])) == 2) print( so.longestUnivaluePath(TreeNode.create_tree([1, 4, 5, 4, 4, None, 5])) == 2)
''' from base import TreeNode class Solution: def findSecondMinimumValue(self, root: TreeNode) -> int: # 层次遍历 min_val = root.val min_list = [] before = [root] while before: after = [] for bb in before: if bb.val > min_val: min_list.append(bb.val) else: if bb.left: after.append(bb.left) if bb.right: after.append(bb.right) before = after return min(val for val in min_list) if min_list else -1 so = Solution() print( so.findSecondMinimumValue(TreeNode.create_tree([2, 2, 5, None, None, 5, 7 ])) == 5) print(so.findSecondMinimumValue(TreeNode.create_tree([2, 2, 2])) == -1)
5398. 统计二叉树中好节点的数目 给你一棵根为 root 的二叉树,请你返回二叉树中好节点的数目。 「好节点」X 定义为:从根到该节点 X 所经过的节点中,没有任何节点的值大于 X 的值。 ''' from base import TreeNode class Solution: def goodNodes(self, root: TreeNode) -> int: self.count = 0 def _find_deep(p, max_before): if not p: return 0 if p.val >= max_before: self.count += 1 _find_deep(p.left, p.val) _find_deep(p.right, p.val) else: _find_deep(p.left, max_before) _find_deep(p.right, max_before) _find_deep(root, - 10 ** 4) return self.count so = Solution() print(so.goodNodes(TreeNode.create_tree([3, 1, 4, 3, None, 1, 5])) == 4) print(so.goodNodes(TreeNode.create_tree([3, 3, None, 4, 2])) == 3) print(so.goodNodes(TreeNode.create_tree([1])) == 1)
class Solution: def pathSum(self, root: TreeNode, sum: int) -> int: # 先序遍历 result = [] def _find_first(p, before): if not p: return else: after = [p.val] if p.val == sum: result.append(1) for bb in before: after.append(bb + p.val) if bb + p.val == sum: result.append(1) _find_first(p.left, after) _find_first(p.right, after) _find_first(root, []) return len(result) so = Solution() print( so.pathSum( TreeNode.create_tree([10, 5, -3, 3, 2, None, 11, 3, -2, None, 1]), 8) == 3)
''' from base import TreeNode class Solution: def rightSideView(self, root: TreeNode): if not root: return [] result = [[root]] while True: after = [] for rr in result[-1]: if rr.left: after.append(rr.left) if rr.right: after.append(rr.right) if not after: break else: result.append(after) return [r[-1].val for r in result] so = Solution() examples = [{"root": [1, 2, 3, None, 5, None, 4], "result": [1, 3, 4]}] for exa in examples: result = so.rightSideView(TreeNode.create_tree(exa["root"])) print(result == exa["result"])
/ \ 9 20 / \ 15 7 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24 思路:中序遍历,找到所有的左叶子节点,求和 ''' from base import TreeNode class Solution: def sumOfLeftLeaves(self, root: TreeNode) -> int: result = [] def _find_left(p): if not p: return else: if p.left: if not p.left.left and not p.left.right: result.append(p.left.val) _find_left(p.left) _find_left(p.right) _find_left(root) return sum(result) so = Solution() print(so.sumOfLeftLeaves(TreeNode.create_tree([3, 9, 20, None, None, 15, 7])) == 24)
提示: 树中的结点数介于 1 和 1000 之间。 node.val 为 0 或 1 。 ''' from base import TreeNode class Solution: def sumRootToLeaf(self, root: TreeNode) -> int: # 层次遍历 求和 before = [[root, root.val]] count = 0 stand = 10 ** 9 + 7 while before: after = [] for bb, val in before: if not bb.left and not bb.right: count = (count + val) % stand else: if bb.left: after.append([bb.left, val * 2 + bb.left.val]) if bb.right: after.append([bb.right, val * 2 + bb.right.val]) before = after return count so = Solution() print(so.sumRootToLeaf(TreeNode.create_tree([1,0,1,0,1,0,1])) == 22)
结点的坡度 3 : 0 结点的坡度 1 : |2-3| = 1 树的坡度 : 0 + 0 + 1 = 1 注意: 任何子树的结点的和不会超过32位整数的范围。 坡度的值不会超过32位整数的范围。 ''' from base import TreeNode class Solution: def findTilt(self, root: TreeNode) -> int: # 后续遍历 self.count = 0 def _find_back(p): if not p: return 0 left = _find_back(p.left) right = _find_back(p.right) self.count += abs(left - right) p.val += left + right return p.val _find_back(root) return self.count so = Solution() print(so.findTilt(TreeNode.create_tree([1, 2, 3])) == 1)
from base import TreeNode class Solution: def rangeSumBST(self, root: TreeNode, L: int, R: int) -> int: result = [] def _find_root(p): if not p: return if p.val <= R and p.val >= L: result.append(p.val) _find_root(p.left) _find_root(p.right) elif p.val < L: _find_root(p.right) elif p.val > R: _find_root(p.left) _find_root(root) return sum(result) so = Solution() print( so.rangeSumBST(TreeNode.create_tree([10, 5, 15, 3, 7, None, 18]), 7, 15) == 32) print( so.rangeSumBST(TreeNode.create_tree([10, 5, 15, 3, 7, 13, 18, 1, None, 6]), 6, 10) == 23)
669. 修剪二叉搜索树 给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。 你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。 ''' from base import TreeNode class Solution: def trimBST(self, root: TreeNode, L: int, R: int) -> TreeNode: def _find_next(p): if not p: return if p.val >= L and p.val <= R: p.left = _find_next(p.left) p.right = _find_next(p.right) return p elif p.val < L: return _find_next(p.right) else: return _find_next(p.left) root = _find_next(root) return root so = Solution() # print(so.trimBST(TreeNode.create_tree([1, 0, 2]), 1, 2)) print(so.trimBST(TreeNode.create_tree([3, 0, 4, None, 2, None, None, 1]), 1, 3))
def _find_next(p): if not p: return if p.val in val_dict.keys(): val_dict[p.val] += 1 else: val_dict[p.val] = 1 _find_next(p.left) _find_next(p.right) _find_next(root) # 获取字典最大值 result = [] max_value = 0 for key, val in val_dict.items(): if val > max_value: max_value = val result = [key] elif val == max_value: result.append(key) else: pass return result so = Solution() print(so.findMode(TreeNode.create_tree([1, None, 2, 2])) == [2]) print(so.findMode(TreeNode.create_tree([1, None, 2])) == [1, 2])
from base import TreeNode class Solution: def isCousins(self, root: TreeNode, x: int, y: int) -> bool: has_dict = dict() before = [root] deep = 1 while before: after = [] for bb in before: if bb: if bb.left: after.append(bb.left) has_dict[bb.left.val] = (bb.val, deep) if bb.right: after.append(bb.right) has_dict[bb.right.val] = (bb.val, deep) before = after deep += 1 if x in has_dict.keys() and y in has_dict.keys(): if has_dict[x][0] != has_dict[y][0] and has_dict[x][1] == has_dict[y][1]: return True return False so = Solution() print(so.isCousins(TreeNode.create_tree([1, 2, 3, 4]), 4, 3) == False) print(so.isCousins(TreeNode.create_tree([1, 2, 3, None, 4, None, 5]), 5, 4) == True) print(so.isCousins(TreeNode.create_tree([1, 2, 3, None, 4]), 2, 3) == False)