class Solution: def getTargetCopy(self, original: TreeNode, cloned: TreeNode, target: TreeNode) -> TreeNode: if not original: return None if target is original: return cloned return self.getTargetCopy(original.left, cloned.left, target) or self.getTargetCopy( original.right, cloned.right, target) if __name__ == "__main__": # 3 tree1 = build_TreeNode([7, 4, 3, None, None, 6, 19]) tree2 = copy.deepcopy(tree1) print(Solution().getTargetCopy(tree1, tree2, tree1.right)) # 7 tree1 = build_TreeNode([1]) tree2 = copy.deepcopy(tree1) print(Solution().getTargetCopy(tree1, tree2, tree1)) # 4 tree1 = build_TreeNode( [8, None, 6, None, 5, None, 4, None, 3, None, 2, None, 1]) tree2 = copy.deepcopy(tree1) print(Solution().getTargetCopy(tree1, tree2, tree1.right.right.right)) # 5
if node.right: queue.append(node.right) d -= 1 print(queue) # 增加新的一行 for node in queue: if node.left: new_node = TreeNode(v) new_node.left = node.left node.left = new_node else: node.left = TreeNode(v) if node.right: new_node = TreeNode(v) new_node.right = node.right node.right = new_node else: node.right = TreeNode(v) return root if __name__ == "__main__": # [4,1,1,2,None,None,6,3,1,5] print(Solution().addOneRow(build_TreeNode([4, 2, 6, 3, 1, 5]), 1, 2)) # [1,2,3,4,null,null,null,5,5] print(Solution().addOneRow(build_TreeNode([1, 2, 3, 4]), 5, 4))
from toolkit import TreeNode, build_TreeNode class Solution: def trimBST(self, root: TreeNode, L: int, R: int) -> TreeNode: def helper(node): if not node: return None if L <= node.val <= R: node.left = helper(node.left) node.right = helper(node.right) return node elif node.val < L: return helper(node.right) elif node.val > R: return helper(node.left) return helper(root) if __name__ == "__main__": print(Solution().trimBST(build_TreeNode([1, 0, 2]), 1, 2)) # [1,None,2] print(Solution().trimBST(build_TreeNode([3, 0, 4, None, 2, None, None, 1]), 1, 3)) # [3,2,None,1]
# 处理根节点的值不相等的情况 if node.val != self.voyage[self.i]: self.ans = [-1] return self.i += 1 if node.left and self.i < len( self.voyage) and node.left.val != self.voyage[self.i]: self.ans.append(node.val) self.dfs(node.right) self.dfs(node.left) else: self.dfs(node.left) self.dfs(node.right) def flipMatchVoyage(self, root: TreeNode, voyage: List[int]) -> List[int]: self.voyage = voyage self.dfs(root) if self.ans and self.ans[0] == -1: return [-1] return self.ans if __name__ == "__main__": print(Solution().flipMatchVoyage(build_TreeNode([1, 2]), [2, 1])) # [-1] print(Solution().flipMatchVoyage(build_TreeNode([1, 2, 3]), [1, 3, 2])) # [1] print(Solution().flipMatchVoyage(build_TreeNode([1, 2, 3]), [1, 2, 3])) # []
node.left = None if node.right and dfs(node.right): node.right = None return not node.left and not node.right and node.val == target dfs(root) if not root.left and not root.right and root.val == target: return None return root if __name__ == "__main__": # [1,null,3,null,4] print(Solution().removeLeafNodes(build_TreeNode([1, 2, 3, 2, None, 2, 4]), 2)) # [1,3,null,null,2] print(Solution().removeLeafNodes(build_TreeNode([1, 3, 3, 3, 2]), 3)) # [1] print(Solution().removeLeafNodes(build_TreeNode([1, 2, None, 2, None, 2]), 2)) # []] print(Solution().removeLeafNodes(build_TreeNode([1, 1, 1]), 1)) # [1,2,3] print(Solution().removeLeafNodes(build_TreeNode([1, 2, 3]), 1))
class Solution: def rob(self, root: TreeNode) -> int: def recursor(node): # 处理当前节点不存在的情况 if not node: return 0, 0 # 左子树最大值(盗窃左节点和不盗窃左节点的两种情况) left1, left2 = recursor(node.left) # 右子树最大值(盗窃右节点和不盗窃右节点的两种情况) right1, right2 = recursor(node.right) # 盗窃当前节点并继续向根节点盗窃所能提供的最大值 most_maybe1 = node.val + left2 + right2 # 不盗窃当前节点并继续向根节点盗窃所能提供的最大值 most_maybe2 = max(left1, left2) + max(right1, right2) # 使用左子树和右子树的最大值,不盗窃当前节点 return most_maybe1, most_maybe2 return max(recursor(root)) if __name__ == "__main__": print(Solution().rob(build_TreeNode([3, 2, 3, None, 3, None, 1]))) # 7 print(Solution().rob(build_TreeNode([3, 4, 5, 1, 3, None, 1]))) # 9 print(Solution().rob(build_TreeNode([4, 2, None, 1, 3]))) # 9
class Solution: def lcaDeepestLeaves(self, root: TreeNode) -> TreeNode: def dfs(node, depth): if not node: return None, 0 if not node.left and not node.right: return node, depth left, depth_left = dfs(node.left, depth + 1) right, depth_right = dfs(node.right, depth + 1) if depth_left == depth_right: return node, depth_left elif depth_left > depth_right: return left, depth_left else: return right, depth_right return dfs(root, 1)[0] if __name__ == "__main__": # [1,2,3] print(Solution().lcaDeepestLeaves(build_TreeNode([1, 2, 3]))) # [4] print(Solution().lcaDeepestLeaves(build_TreeNode([1, 2, 3, 4]))) # [2,4,5] print(Solution().lcaDeepestLeaves(build_TreeNode([1, 2, 3, 4, 5])))
if node: stack.append(node.left) else: stack.pop() if not stack: break now = stack.pop() self.ans.append(now.val) stack.append(now.right) print(stack) def next(self) -> int: return self.ans.pop(0) def hasNext(self) -> bool: return len(self.ans) > 0 if __name__ == "__main__": root = build_TreeNode([7, 3, 15, None, None, 9, 20]) obj = BSTIterator(root) print(obj.next()) # 3 print(obj.next()) # 7 print(obj.hasNext()) # True print(obj.next()) # 9 print(obj.hasNext()) # True print(obj.next()) # 15 print(obj.hasNext()) # True print(obj.next()) # 20 print(obj.hasNext()) # False
class Solution: def __init__(self): self.depth = None self.father = None def isCousins(self, root: TreeNode, x: int, y: int) -> bool: def helper(node, depth=0, father=None): if node: if node.val == x or node.val == y: if self.depth is None: self.depth = depth + 1 self.father = father else: if self.depth == depth + 1 and self.father != father: return True else: return False return helper(node.left, depth + 1, node.val) or helper( node.right, depth + 1, node.val) return helper(root) if __name__ == "__main__": print(Solution().isCousins(build_TreeNode([1, 2, 3, 4]), 4, 3)) # False print(Solution().isCousins(build_TreeNode([1, 2, 3, None, 4, None, 5]), 5, 4)) # True print(Solution().isCousins(build_TreeNode([1, 2, 3, None, 4]), 2, 3)) # False
from toolkit import TreeNode from toolkit import build_TreeNode class Solution: def findBottomLeftValue(self, root: TreeNode) -> int: ans = root.val queue = collections.deque([root]) while queue: for _ in range(len(queue)): node = queue.popleft() if node.left: queue.append(node.left) if node.right: queue.append(node.right) if queue: ans = queue[0].val return ans if __name__ == "__main__": # 1 print(Solution().findBottomLeftValue(build_TreeNode([2, 1, 3]))) # 7 print(Solution().findBottomLeftValue(build_TreeNode([1, 2, 3, 4, None, 5, 6, None, None, 7])))
from toolkit import TreeNode, build_TreeNode class Solution: def findTarget(self, root: TreeNode, k: int) -> bool: def helper(node): if not node: return [] return helper(node.left) + [node.val] + helper(node.right) nums = helper(root) hashmap = [] for n in nums: if k - n not in hashmap: hashmap.append(n) else: return True else: return False if __name__ == "__main__": print(Solution().findTarget(build_TreeNode([5, 3, 6, 2, 4, None, 7]), 9)) # True print(Solution().findTarget(build_TreeNode([5, 3, 6, 2, 4, None, 7]), 28)) # False
from toolkit import TreeNode from toolkit import build_TreeNode class Solution: def pruneTree(self, root: TreeNode) -> TreeNode: if root: root.left = self.pruneTree(root.left) root.right = self.pruneTree(root.right) if root.val == 1 or root.left or root.right: return root if __name__ == "__main__": # [1,None,0,None,1] print(Solution().pruneTree(build_TreeNode([1, None, 0, 0, 1]))) # [1,None,1,None,1] print(Solution().pruneTree(build_TreeNode([1, 0, 1, 0, 0, 0, 1]))) # [1,1,0,1,1,None,1] print(Solution().pruneTree(build_TreeNode([1, 1, 0, 1, 1, 0, 1, 0])))
from toolkit import TreeNode, build_TreeNode class Solution: def __init__(self): self.val = None def isUnivalTree(self, root: TreeNode) -> bool: self.val = root.val def helper(node): if not node: return True elif node.val != self.val: return False else: return helper(node.left) and helper(node.right) return helper(root) if __name__ == "__main__": tree = build_TreeNode([1, 1, 1, 1, 1, None, 1]) print(Solution().isUnivalTree(tree)) # True tree = build_TreeNode([2, 2, 2, 5, 2]) print(Solution().isUnivalTree(tree)) # False
class Solution: def rightSideView(self, root: TreeNode) -> List[int]: # 处理特殊情况 if not root: return [] # 处理一般情况 ans = [root.val] stack = [(root, 0)] while stack: node, level = stack[-1] if node.right: stack.append((node.right, level + 1)) if level + 1 == len(ans): ans.append(node.right.val) else: while stack: node, level = stack.pop() if node.left: stack.append((node.left, level + 1)) if level + 1 == len(ans): ans.append(node.left.val) break return ans if __name__ == "__main__": print(Solution().rightSideView(build_TreeNode([1, 2, 3, None, 5, None, 4]))) # [1,3,4] print(Solution().rightSideView(build_TreeNode([1, 2]))) # [1,2]
return 0 left_length = 0 right_length = 0 if node.left: if node.val == node.left.val: left_length = helper(node.left) + 1 else: helper(node.left) if node.right: if node.val == node.right.val: right_length = helper(node.right) + 1 else: helper(node.right) if left_length > 0 and right_length > 0: self.max = max(self.max, left_length + right_length) else: self.max = max(self.max, left_length, right_length) return max(left_length, right_length) helper(root) return self.max if __name__ == "__main__": print(Solution().longestUnivaluePath( build_TreeNode([5, 4, 5, 1, 1, None, 5]))) # 2 print(Solution().longestUnivaluePath( build_TreeNode([1, 4, 5, 4, 4, None, 5]))) # 2
left = 0 if node.right: right = dfs(node.right)[0] else: right = 0 self.max = max(self.max, left, right) return left + 1, right + 1 dfs(root) return self.max if __name__ == "__main__": # 3 print(Solution().longestZigZag( build_TreeNode([ 1, None, 1, 1, 1, None, None, 1, 1, None, 1, None, None, None, 1, None, 1 ]))) # 4 print(Solution().longestZigZag( build_TreeNode([1, 1, 1, None, 1, None, None, 1, 1, None, 1]))) # 0 print(Solution().longestZigZag(build_TreeNode([1])))
self.this = False # 上一个为目标节点 def inorderSuccessor(self, root: TreeNode, p: TreeNode) -> TreeNode: self.aim = p self.dfs(root) return self.ans def dfs(self, node): if node: self.dfs(node.left) if self.this: self.ans = node self.this = False else: if node == self.aim: self.this = True if node.right: self.dfs(node.right) if __name__ == "__main__": # 2 tree = build_TreeNode([2, 1, 3]) print(Solution().inorderSuccessor(tree, tree.left)) # None tree = build_TreeNode([5, 3, 6, 2, 4, None, None, 1]) print(Solution().inorderSuccessor(tree, tree.right))
from toolkit import TreeNode, build_TreeNode class Solution: def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': pass if __name__ == "__main__": tree = build_TreeNode([6, 2, 8, 0, 4, 7, 9, None, None, 3, 5]) print(Solution().lowestCommonAncestor(tree, tree.left, tree.right)) # 6 print(Solution().lowestCommonAncestor(tree, tree.left, tree.left.right)) # 2
from toolkit import TreeNode, build_TreeNode class Solution: def tree2str(self, t: TreeNode) -> str: def helper(node): if not node: return "" if node.left and node.right: return str(node.val) + "(" + helper(node.left) + ")(" + helper( node.right) + ")" elif node.left: return str(node.val) + "(" + helper(node.left) + ")" elif node.right: return str(node.val) + "()(" + helper(node.right) + ")" else: return str(node.val) return helper(t) if __name__ == "__main__": print(Solution().tree2str(build_TreeNode([1, 2, 3, 4]))) # 1(2(4))(3) print(Solution().tree2str(build_TreeNode([1, 2, 3, None, 4]))) # 1(2()(4))(3)
def __init__(self): self.ans = [] def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]: def recursor(node, stack, _sum): if node: stack.append(node.val) # 记录当前路径 _sum += node.val # 计算当前路径和 if not node.left and not node.right: if _sum == sum: self.ans.append(stack) else: if node.left: recursor(node.left, stack.copy(), _sum) if node.right: recursor(node.right, stack.copy(), _sum) recursor(root, [], 0) return self.ans if __name__ == "__main__": # [ # [5,4,11,2], # [5,8,4,5] # ] print(Solution().pathSum( build_TreeNode([5, 4, 8, 11, None, 13, 4, 7, 2, None, None, 5, 1]), 22))
if node.left and node.right: left = dfs(node.left) right = dfs(node.right) for i in range(distance - 1): for j in range(0, distance - 1 - i): self.ans += left[i] * right[j] return [0] + [left[i] + right[i] for i in range(distance - 1)] elif node.left: left = dfs(node.left) return [0] + left[:-1] elif node.right: right = dfs(node.right) return [0] + right[:-1] else: return [1] + [0] * (distance - 2) dfs(root) return self.ans if __name__ == "__main__": print(Solution().countPairs(build_TreeNode([1, 2, 3, None, 4]), 3)) # 1 print(Solution().countPairs(build_TreeNode([1, 2, 3, 4, 5, 6, 7]), 3)) # 2 print(Solution().countPairs( build_TreeNode( [7, 1, 4, 6, None, 5, 3, None, None, None, None, None, 2]), 3)) # 1 print(Solution().countPairs(build_TreeNode([1100]), 1)) # 0 print(Solution().countPairs(build_TreeNode([1, 1, 1]), 2)) # 1
from toolkit import TreeNode from toolkit import build_TreeNode class Solution: def subtreeWithAllDeepest(self, root: TreeNode) -> TreeNode: # 计算二叉树的最大深度 def max_depth(node): if not node: return 0 return max(max_depth(node.left), max_depth(node.right)) + 1 def recursor(node): depth_left = max_depth(node.left) depth_right = max_depth(node.right) if depth_left == depth_right: return node else: return recursor( node.left) if depth_left > depth_right else recursor( node.right) return recursor(root) if __name__ == "__main__": # [2,7,4] print(Solution().subtreeWithAllDeepest( build_TreeNode([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4])))
class Solution: def inorderTraversal(self, root: TreeNode) -> List[int]: # 处理特殊情况 if not root: return [] stack = [root] ans = [] while stack: if now := stack[-1]: stack.append(now.left) else: stack.pop() if not stack: break now = stack.pop() ans.append(now.val) stack.append(now.right) return ans if __name__ == "__main__": print(Solution().inorderTraversal(build_TreeNode([1, None, 2, 3]))) # [1,3,2] print(Solution().inorderTraversal(build_TreeNode([1, 2]))) # [2,1] print(Solution().inorderTraversal(build_TreeNode([3, 1, None, None, 2]))) # [1,2,3]
class Solution: def __init__(self): self.ans = collections.defaultdict(list) def verticalTraversal(self, root: TreeNode) -> List[List[int]]: def dfs(node, idx, level): if node: self.ans[idx].append((node.val, level)) if node.left: dfs(node.left, idx - 1, level + 1) if node.right: dfs(node.right, idx + 1, level + 1) dfs(root, 0, 0) ans = [] for k in sorted(self.ans.keys()): ans.append([ elem[0] for elem in sorted(self.ans[k], key=lambda x: (x[1], x[0])) ]) return ans if __name__ == "__main__": # [[9],[3,15],[20],[7]] print(Solution().verticalTraversal( build_TreeNode([3, 9, 20, None, None, 15, 7]))) # [[4],[2],[1,5,6],[3],[7]] print(Solution().verticalTraversal(build_TreeNode([1, 2, 3, 4, 5, 6, 7])))
self.min1 = float("inf") self.min2 = float("inf") def findSecondMinimumValue(self, root: TreeNode) -> int: def helper(node): if node.val < self.min1: self.min2 = self.min1 self.min1 = node.val elif self.min1 < node.val < self.min2: self.min2 = node.val if node.left and node.right: if node.left.val < self.min2: helper(node.left) if node.right.val < self.min2: helper(node.right) helper(root) if self.min2 == float("inf"): return -1 else: return int(self.min2) if __name__ == "__main__": print(Solution().findSecondMinimumValue( build_TreeNode([2, 2, 5, None, None, 5, 7]))) # 5 print(Solution().findSecondMinimumValue(build_TreeNode([2, 2, 2]))) # -1 print(Solution().findSecondMinimumValue( build_TreeNode([2, 2, 5, None, None, 5, 5]))) # 5
from toolkit import TreeNode,build_TreeNode class Solution: def hasPathSum(self, root: TreeNode, sum: int) -> bool: if root is None: return False node_dict = {root: root.val} while len(node_dict) > 0: temp_node_dict = {} for node in node_dict: node_value = node_dict[node] if node.left is None and node.right is None: if node_value == sum: return True if node.left is not None: temp_node_dict[node.left] = node_value + node.left.val if node.right is not None: temp_node_dict[node.right] = node_value + node.right.val node_dict = temp_node_dict return False if __name__ == "__main__": print(Solution().hasPathSum(build_TreeNode([5, 4, 8, 11, None, 13, 4, 7, 2, None, None, None, 1]), 22)) print(Solution().hasPathSum(build_TreeNode([1]), 1))
import collections from typing import List from toolkit import TreeNode from toolkit import build_TreeNode class Solution: def levelOrder(self, root: TreeNode) -> List[int]: if not root: return [] ans = [] queue = collections.deque([root]) while queue: node = queue.popleft() ans.append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) return ans if __name__ == "__main__": # [3,9,20,15,7] print(Solution().levelOrder(build_TreeNode([3, 9, 20, None, None, 15, 7])))
if not root: return 0., 0. # 递归左子树和右子树 total_left, full_left = self.dfs(root.left) total_right, full_right = self.dfs(root.right) # 计算树的总计运行时间 total_root = root.val + total_left + total_right if total_left < total_right: total_left, total_right = total_right, total_left full_left, full_right = full_right, full_left # 处理左子节点和右子节点均可以完全双线程的情况 if total_left - 2 * full_left <= total_right: full_root = (total_left + total_right) / 2 # 处理左子节点和右子节点不能完全双线程的情况 else: full_root = total_right + full_left return total_root, full_root if __name__ == "__main__": print(Solution().minimalExecTime(build_TreeNode([47, 74, 31]))) # 121 print(Solution().minimalExecTime(build_TreeNode([15, 21, None, 24, None, 27, 26]))) # 87 print(Solution().minimalExecTime(build_TreeNode([1, 3, 2, None, None, 4, 4]))) # 7.5 print(Solution().minimalExecTime(build_TreeNode([75, None, 18, None, 20, 27, 36]))) # 149
from toolkit import TreeNode, build_TreeNode class Solution: def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode: def helper(node1, node2): if node1 and node2: node = TreeNode(node1.val + node2.val) node.left = helper(node1.left, node2.left) node.right = helper(node1.right, node2.right) return node elif node1: return node1 elif node2: return node2 else: return None return helper(t1, t2) if __name__ == "__main__": # [3,4,5,5,4,None,7] print(Solution().mergeTrees(build_TreeNode([1, 3, 2, 5]), build_TreeNode([2, 1, 3, None, 4, None, 7])))
from toolkit import TreeNode, build_TreeNode class Solution: def minDepth(self, root: TreeNode) -> int: if root is None: return 0 level = 1 node_list = [root] while len(node_list) > 0: temp_node_list = [] for node in node_list: if node.left is None and node.right is None: return level if node.left is not None: temp_node_list.append(node.left) if node.right is not None: temp_node_list.append(node.right) node_list = temp_node_list level += 1 return level if __name__ == "__main__": print(Solution().minDepth(build_TreeNode([3, 9, 20, None, None, 15, 7]))) # 2 print(Solution().minDepth(build_TreeNode([1, 2]))) print(Solution().minDepth(build_TreeNode([1, 2, 3, 4, 5])))