class Solution: def inorder(self, node, lst): if node: self.inorder(node.left, lst) lst.append(node.val) self.inorder(node.right, lst) def balanceBST(self, root: TreeNode) -> TreeNode: lst = [] self.inorder(root, lst) size = len(lst) return self.dfs(lst, 0, size - 1) def dfs(self, lst, l, r): if l > r: return None if l == r: return TreeNode(lst[l]) else: m = (l + r) // 2 root = TreeNode(lst[m]) root.left = self.dfs(lst, l, m - 1) root.right = self.dfs(lst, m + 1, r) return root if __name__ == "__main__": print(Solution().balanceBST(build_TreeNode([1, None, 2, None, 3, None, 4])))
class Solution: def __init__(self): self.ans = 0 def longestConsecutive(self, root: TreeNode) -> int: self.dfs(root, 0, float("NAN")) return self.ans def dfs(self, node, now_length, now_val): if node: if node.val == now_val + 1: self.ans = max(self.ans, now_length + 1) self.dfs(node.left, now_length + 1, node.val) self.dfs(node.right, now_length + 1, node.val) else: self.ans = max(self.ans, 1) self.dfs(node.left, 1, node.val) self.dfs(node.right, 1, node.val) if __name__ == "__main__": # 3 print(Solution().longestConsecutive( build_TreeNode([1, None, 3, 2, 4, None, None, None, 5]))) # 2 print(Solution().longestConsecutive( build_TreeNode([2, None, 3, 2, None, 1])))
node = now_level.popleft() if node == u: if now_level: return now_level.popleft() else: return None if node.left: next_level.append(node.left) if node.right: next_level.append(node.right) now_level = next_level return None if __name__ == "__main__": # 5 tree = build_TreeNode([1, 2, 3, None, 4, 5, 6]) print(Solution().findNearestRightNode(tree, tree.left.right)) # None tree = build_TreeNode([3, None, 4, 2]) print(Solution().findNearestRightNode(tree, tree.right.left)) # None tree = build_TreeNode([1]) print(Solution().findNearestRightNode(tree, tree)) # 2 tree = build_TreeNode([3, 4, 2, None, None, None, 1]) print(Solution().findNearestRightNode(tree, tree.left))
def dfs(self, node): """返回节点的上一个三叉路,有几个放置的导航""" if not node: return 0 left = self.dfs(node.left) right = self.dfs(node.right) if node.left and node.right: if left == 0 and right == 0: self.ans += 1 return 1 elif left == 0 or right == 0: return 1 else: return 2 elif node.left: return left elif node.right: return right else: return 0 if __name__ == "__main__": print(Solution().navigation(build_TreeNode([1, 2, None, 3, 4]))) # 2 print(Solution().navigation(build_TreeNode([1, 2, 3, 4]))) # 1 print(Solution().navigation(build_TreeNode([1, 2, 3, 4, 5]))) # 2 print(Solution().navigation( build_TreeNode([1, 2, None, 3, 4, None, None, 5, 6, 7, 8, 9, 10]))) # 3
from LeetTool import TreeNode from LeetTool import build_TreeNode # Definition for a binary tree node. class Solution: def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': pass if __name__ == "__main__": tree = build_TreeNode([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4]) print(Solution().lowestCommonAncestor(tree, tree.left, tree.right)) # 3 tree = build_TreeNode([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4]) print(Solution().lowestCommonAncestor(tree, tree.left, tree.left.right.right)) # 5 tree = build_TreeNode([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4]) node2 = TreeNode(10) print(Solution().lowestCommonAncestor(tree, tree.left, node2)) # None
# 处理左子节点 if left: self.dfs(left) # 处理当前节点 self.last_node.right = node node.left = self.last_node self.last_node = node # 处理右子节点 if right and node.val != self.max_node.val: self.dfs(right) # print("END:", node.val, # "(", node.left.val if node.left else None, node.right.val if node.right else None, ")") if __name__ == "__main__": # [1,2,3,4,5] Solution().treeToDoublyList(build_TreeNode([4, 2, 5, 1, 3])) # [1,2,3] Solution().treeToDoublyList(build_TreeNode([2, 1, 3])) # [] Solution().treeToDoublyList(build_TreeNode([])) # [1] Solution().treeToDoublyList(build_TreeNode([1]))
# 判断两棵子树是否符合二叉搜索树性质 if not bool1 or not bool2: return False, -1, 0, 0 # 判断当前节点是否符合二叉搜索树性质 if node.val <= l2 or node.val >= r1: return False, -1, 0, 0 l = l1 if node.left else node.val r = r2 if node.right else node.val val = val1 + node.val + val2 self.ans = max(self.ans, val) return True, val, l, r if __name__ == "__main__": print(Solution().maxSumBST( build_TreeNode( [1, 4, 3, 2, 4, 2, 5, None, None, None, None, None, None, 4, 6]))) # 20 print(Solution().maxSumBST(build_TreeNode([4, 3, None, 1, 2]))) # 2 print(Solution().maxSumBST(build_TreeNode([-4, -2, -5]))) # 0 print(Solution().maxSumBST(build_TreeNode([2, 1, 3]))) # 6 print(Solution().maxSumBST(build_TreeNode([5, 4, 8, 3, None, 6, 3]))) # 7 print(Solution().maxSumBST(build_TreeNode([1, None, 10, -5, 20]))) # 25 print(Solution().maxSumBST( build_TreeNode( [8, 9, 8, None, 9, None, 1, None, None, -3, 5, None, -2, None, 6]))) # 11
ans = [] if left[-1] == leaf[0]: ans += [p.val for p in left[:-1]] else: ans += [p.val for p in left] if leaf[-1] == right[0]: ans += [p.val for p in leaf[:-1]] else: ans += [p.val for p in leaf] if right[-1] == left[0]: ans += [p.val for p in right[:-1]] else: ans += [p.val for p in right] return ans if __name__ == "__main__": # [1] print(Solution().boundaryOfBinaryTree(build_TreeNode([1]))) # [1,3,4,2] print(Solution().boundaryOfBinaryTree(build_TreeNode([1, None, 2, 3, 4]))) # [1,2,4,7,8,9,10,6,3] print(Solution().boundaryOfBinaryTree( build_TreeNode([1, 2, 3, 4, 5, 6, None, None, None, 7, 8, 9, 10])))
from LeetTool import TreeNode from LeetTool import build_TreeNode class Solution: def __init__(self): self.total = 0 def bstToGst(self, root: TreeNode) -> TreeNode: if root: self.bstToGst(root.right) self.total += root.val root.val = self.total self.bstToGst(root.left) return root if __name__ == "__main__": print(Solution().bstToGst(build_TreeNode([5, 2, 13]))) # [18,20,13]
left_bool, left_num, left_min, left_max = self.dfs(node.left) if left_bool and left_max < node.val: if self.ans_num < left_num + 1: self.ans_node, self.ans_num = node, left_num + 1 return True, left_num + 1, left_min, node.val else: return False, None, None, None elif node.right: right_bool, right_num, right_min, right_max = self.dfs(node.right) if right_bool and node.val < right_min: if self.ans_num < right_num + 1: self.ans_node, self.ans_num = node, right_num + 1 return True, right_num + 1, node.val, right_max else: return False, None, None, None else: if self.ans_num < 1: self.ans_node, self.ans_num = node, 1 return True, 1, node.val, node.val if __name__ == "__main__": # 3 print(Solution().largestBSTSubtree( build_TreeNode([10, 5, 15, 1, 8, None, 7]))) # 2 print(Solution().largestBSTSubtree( build_TreeNode( [4, 2, 7, 2, 3, 5, None, 2, None, None, None, None, None, 1])))
elif node.right: right1, right2, right3, right4 = self.dfs(node.right) if v == right2 + 1: now1, now2 = right1, v else: now1, now2 = v, v if v == right3 - 1: now3, now4 = v, right4 else: now3, now4 = v, v else: now1, now2, now3, now4 = v, v, v, v # 计算长度最大值 len1 = now2 - now1 + 1 len2 = now4 - now3 + 1 len3 = len1 + len2 - 1 if now2 == now3 else 0 self.ans = max(self.ans, len1, len2, len3) return now1, now2, now3, now4 if __name__ == "__main__": # 2 print(Solution().longestConsecutive(build_TreeNode([1, 2, 3]))) # 3 print(Solution().longestConsecutive(build_TreeNode([2, 1, 3])))
from LeetTool import TreeNode from LeetTool import build_TreeNode class Solution: def maxValue(self, root: TreeNode, k: int) -> int: pass if __name__ == "__main__": print(Solution().maxValue(root=build_TreeNode([5, 2, 3, 4]), k=2)) # 12 print(Solution().maxValue(root=build_TreeNode([4, 1, 3, 9, None, None, 2]), k=2)) # 16
from LeetTool import TreeNode from LeetTool import build_TreeNode class Solution: def upsideDownBinaryTree(self, root: TreeNode) -> TreeNode: if not root: return None ans = TreeNode(root.val) while root.left: node = TreeNode(root.left.val) node.right = ans node.left = root.right ans = node root = root.left return ans if __name__ == "__main__": # [4,5,2,#,#,3,1] print(Solution().upsideDownBinaryTree(build_TreeNode([1, 2, 3, 4, 5])))
ans.append(self.lst[left]) left -= 1 elif right < len(self.lst): ans.append(self.lst[right]) right += 1 else: break return ans def inorder(self, node): if node: self.inorder(node.left) self.lst.append(node.val) self.inorder(node.right) if __name__ == "__main__": # [4,3] print(Solution().closestKValues(build_TreeNode([4, 2, 5, 1, 3]), 3.714286, 2)) # [1] print(Solution().closestKValues(build_TreeNode([1]), 0, 1)) # [1] print(Solution().closestKValues(build_TreeNode([1]), 4.428571, 1)) # [1] print(Solution().closestKValues(build_TreeNode([1, None, 8]), 3, 1))
if node: # 计算更新当前节点的最近叶子节点 if parent: d1, n1 = self.hashmap[node] d2, n2 = self.hashmap[parent] if d1 > d2 + 1: self.hashmap[node] = d2 + 1, n2 # 寻找目标节点 if node.val == k: return self.hashmap[node][1] else: return self.dfs2(node.left, node, k) or self.dfs2( node.right, node, k) else: return None if __name__ == "__main__": # 2 或 3 print(Solution().findClosestLeaf(build_TreeNode([1, 3, 2]), k=1)) # 1 print(Solution().findClosestLeaf(build_TreeNode([1]), k=1)) # 3 print(Solution().findClosestLeaf(build_TreeNode( [1, 2, 3, 4, None, None, None, 5, None, 6]), k=2))
actual_idx = idx - self.min_idx self.ans[actual_idx].append((h, node.val)) self.dfs(node.left, idx - 1, h + 1) self.dfs(node.right, idx + 1, h + 1) if __name__ == "__main__": # [ # [9], # [3,15], # [20], # [7] # ] print(Solution().verticalOrder( build_TreeNode([3, 9, 20, None, None, 15, 7]))) # [ # [4], # [9], # [3,0,1], # [8], # [7] # ] print(Solution().verticalOrder(build_TreeNode([3, 9, 8, 4, 0, 1, 7]))) # [ # [4], # [9,5], # [3,0,1], # [8,2],
from typing import List from LeetTool import TreeNode from LeetTool import build_TreeNode class Solution: def splitBST(self, root: TreeNode, V: int) -> List[TreeNode]: if not root: return [None, None] if V < root.val: left, right = self.splitBST(root.left, V) root.left = right return [left, root] elif root.val < V: left, right = self.splitBST(root.right, V) root.right = left return [root, right] else: right = root.right root.right = None return [root, right] if __name__ == "__main__": # [[2,1],[4,3,6,null,null,5,7]] print(Solution().splitBST(build_TreeNode([4, 2, 6, 1, 3, 5, 7]), 2))
class Solution: def __init__(self): self.vals = set() def checkEqualTree(self, root: TreeNode) -> bool: total = root.val + self.dfs(root.left) + self.dfs( root.right) # 根节点不能是答案 return total / 2 in self.vals def dfs(self, node): if node: v = node.val + self.dfs(node.left) + self.dfs(node.right) self.vals.add(v) return v else: return 0 if __name__ == "__main__": # True print(Solution().checkEqualTree( build_TreeNode([5, 10, 10, None, None, 2, 3]))) # False print(Solution().checkEqualTree( build_TreeNode([1, 2, 10, None, None, 2, 20]))) # False print(Solution().checkEqualTree(build_TreeNode([0, -1, 1])))
from typing import List from LeetTool import TreeNode from LeetTool import build_TreeNode class Solution: def __init__(self): self.ans = [] def findLeaves(self, root: TreeNode) -> List[List[int]]: self.dfs(root) return self.ans def dfs(self, node): if node: height = 1 + max(self.dfs(node.left), self.dfs(node.right)) if len(self.ans) < height: self.ans.append([]) self.ans[height - 1].append(node.val) return height else: return 0 if __name__ == "__main__": # [[4,5,3],[2],[1]] print(Solution().findLeaves(build_TreeNode([1, 2, 3, 4, 5])))
class Solution: def maxLevelSum(self, root: TreeNode) -> int: level = collections.deque([root]) ans_idx, ans_val = 1, root.val level_idx = 1 while level: level_val = 0 for i in range(len(level)): p = level.popleft() level_val += p.val if p.left: level.append(p.left) if p.right: level.append(p.right) if ans_val < level_val: ans_idx, ans_val = level_idx, level_val level_idx += 1 return ans_idx if __name__ == "__main__": # 2 print(Solution().maxLevelSum(build_TreeNode([1, 7, 0, 7, -8, None, None]))) # 2 print(Solution().maxLevelSum( build_TreeNode( [989, None, 10250, 98693, -89388, None, None, None, -32127])))
if not n1 and not n2: return True elif not n1 or not n2: return False elif n1.val != n2.val: return False else: return self.maybe_find(n1.left, n2.left) and self.maybe_find( n1.right, n2.right) def checkSubTree(self, t1: TreeNode, t2: TreeNode) -> bool: if not t2: return True elif not t1: return False elif t1.val == t2.val and self.maybe_find(t1, t2): return True else: return self.checkSubTree(t1.left, t2) or self.checkSubTree( t1.right, t2) if __name__ == "__main__": # True print(Solution().checkSubTree(build_TreeNode([1, 2, 3]), build_TreeNode([2]))) # False print(Solution().checkSubTree(build_TreeNode([1, None, 2, 4]), build_TreeNode([3, 2])))
elif node.left: left = dfs(now + node.val, node.left) return node.val + left elif node.right: right = dfs(now + node.val, node.right) return node.val + right else: return node.val val = dfs(0, root) return root if val >= limit else None if __name__ == "__main__": # [1,2,3,4,null,null,7,8,9,null,14] print(Solution().sufficientSubset( build_TreeNode( [1, 2, 3, 4, -99, -99, 7, 8, 9, -99, -99, 12, 13, -99, 14]), 1)) # [5,4,8,11,null,17,4,7,null,null,null,5] print(Solution().sufficientSubset( build_TreeNode([5, 4, 8, 11, None, 17, 4, 7, 1, None, None, 5, 3]), 22)) # [] print(Solution().sufficientSubset(build_TreeNode([5, -6, -6]), 0)) # [1,null,-3,4] print(Solution().sufficientSubset( build_TreeNode([1, 2, -3, -5, None, 4, None]), -1))
return self.now.val else: val = self.now.val while self.parent: self.now = self.parent.pop() if self.now.val < val: return self.now.val if self.now.left and self.now.left.val < val: self.parent.append(self.now) self.now = self.now.left while self.now.right: self.parent.append(self.now) self.now = self.now.right return self.now.val if __name__ == "__main__": bst = BSTIterator(build_TreeNode([7, 3, 15, None, None, 9, 20])) print(bst.next()) # 3 print(bst.next()) # 7 print(bst.prev()) # 3 print(bst.next()) # 7 print(bst.hasNext()) # True print(bst.next()) # 9 print(bst.next()) # 15 print(bst.next()) # 20 print(bst.hasNext()) # False print(bst.hasPrev()) # True print(bst.prev()) # 15 print(bst.prev()) # 9
from LeetTool import TreeNode from LeetTool import build_TreeNode class Solution: def convertBiNode(self, root: TreeNode, bigger=None) -> TreeNode: if root: # 处理当前节点 left, right = root.left, root.right root.left = None # 处理当前节点的右侧节点 if right: root.right = self.convertBiNode(right, bigger) else: root.right = bigger if left: return self.convertBiNode(left, root) else: return root if __name__ == "__main__": # [] print(Solution().convertBiNode(None)) # [0,None,1,None,2,None,3,None,4,None,5,None,6] print(Solution().convertBiNode(build_TreeNode([4, 2, 5, 1, 3, None, 6, 0])))
self.inorder(node.right, lst) def twoSumBSTs(self, root1: TreeNode, root2: TreeNode, target: int) -> bool: lst1, lst2 = [], [] self.inorder(root1, lst1) self.inorder(root2, lst2) s1, s2 = len(lst1), len(lst2) i1, i2 = 0, s2 - 1 while i1 < s1 and i2 >= 0: val = lst1[i1] + lst2[i2] if val < target: i1 += 1 elif val > target: i2 -= 1 else: return True return False if __name__ == "__main__": print(Solution().twoSumBSTs(build_TreeNode([2, 1, 4]), build_TreeNode([1, 0, 3]), 5)) # True print(Solution().twoSumBSTs(build_TreeNode([0, -10, 10]), build_TreeNode([5, 1, 7, 0, 2]), 18)) # False print(Solution().twoSumBSTs(build_TreeNode([0, -10, 10]), build_TreeNode([5, 1, 7, 0, 2]), 17)) # True
from LeetTool import TreeNode from LeetTool import build_TreeNode class Solution: def __init__(self): self.ans = 0 def maximumAverageSubtree(self, root: TreeNode) -> float: self.dfs(root) return self.ans def dfs(self, node): if node: s1, n1 = self.dfs(node.left) s2, n2 = self.dfs(node.right) s, n = s1 + s2 + node.val, n1 + n2 + 1 self.ans = max(self.ans, s / n) return s, n else: return 0, 0 if __name__ == "__main__": # 6.00000 print(Solution().maximumAverageSubtree(build_TreeNode([5, 6, 1])))
self.lst.append(node.val) last = 0 for i in range(len(self.lst) - 1, -1, -1): last += self.lst[i] if last == self.sum: self.ans += 1 if node.left: self.dfs(node.left) if node.right: self.dfs(node.right) # print(self.total, self.lst, self.ans) self.lst.pop() self.total -= node.val if __name__ == "__main__": # 3 print(Solution().pathSum( build_TreeNode([5, 4, 8, 11, None, 13, 4, 7, 2, None, None, 5, 1]), 22)) # 1 print(Solution().pathSum(build_TreeNode([-2, None, -3]), -3)) # 4 print(Solution().pathSum(build_TreeNode([0, 1, 1]), 1))
self.arr = arr return self.dfs(root, 0) def dfs(self, node, i): if node and i < len(self.arr) and node.val == self.arr[i]: if i == len(self.arr) - 1 and not node.left and not node.right: return True else: return self.dfs(node.left, i + 1) or self.dfs( node.right, i + 1) else: return False if __name__ == "__main__": # True print(Solution().isValidSequence( build_TreeNode([0, 1, 0, 0, 1, 0, None, None, 1, 0, 0]), [0, 1, 0, 1])) # False print(Solution().isValidSequence( build_TreeNode([0, 1, 0, 0, 1, 0, None, None, 1, 0, 0]), [0, 0, 1])) # False print(Solution().isValidSequence( build_TreeNode([0, 1, 0, 0, 1, 0, None, None, 1, 0, 0]), [0, 1, 1])) # False print(Solution().isValidSequence( build_TreeNode([2, 9, 3, None, 1, None, 2, None, 8]), [2, 9, 1, 8, 0]))
from LeetTool import TreeNode from LeetTool import build_TreeNode class Solution: def closestValue(self, root: TreeNode, target: float) -> int: smaller, bigger = float("-inf"), float("inf") while root: if root.val < target: smaller = root.val root = root.right elif target < root.val: bigger = root.val root = root.left else: return int(target) if bigger - target > target - smaller: return smaller else: return bigger if __name__ == "__main__": # 4 print(Solution().closestValue(build_TreeNode([4, 2, 5, 1, 3]), 3.714286)) # 1 print(Solution().closestValue(build_TreeNode([1]), 4.428571))
i1 += 1 else: lst.append(right[i2]) i2 += 1 ans.append(lst) return ans elif root.left: ans = [] for lst in self.BSTSequences(root.left): ans.append([root.val] + lst) return ans elif root.right: ans = [] for lst in self.BSTSequences(root.right): ans.append([root.val] + lst) return ans else: return [[root.val]] if __name__ == "__main__": # [ # [2,1,3], # [2,3,1] # ] print(Solution().BSTSequences(build_TreeNode([2, 1, 3]))) # [[5,2,1,4,3],[5,2,4,1,3],[5,2,4,3,1]] print(Solution().BSTSequences( build_TreeNode([5, 2, None, 1, 4, None, None, 3])))