from src.common.tree import create_treenode from src.common.list import ListNode class Solution: def treeToDoublyList(self, root): def dfs(node): nonlocal pre, head if not node: return dfs(node.left) if pre: pre.right, node.left = node, pre else: head = node pre = node dfs(node.right) if not root: return pre = head = None dfs(root) head.left, pre.right = pre, head return head if __name__ == '__main__': s = Solution() root = create_treenode([4, 2, 5, 1, 3]) print(root) print('1', s.treeToDoublyList(root))
因此,数字总和 = 495 + 491 + 40 = 1026 提示: 树中节点的数目在范围 [1, 1000] 内 0 <= Node.val <= 9 树的深度不超过 10 ''' class Solution: def sumNumbers(self, root) -> int: if not root:return 0 def dfs(node,pre_value): if not node: return 0 total =pre_value*10+node.value if not node.left and not node.right: return total else: return dfs(node.left,total) + dfs(node.right,total) return dfs(root,0) if __name__ =='__main__': s =Solution() from src.common.tree import create_treenode root = create_treenode([1, 2, 3]) print(root) print('1',s.sumNumbers(root)) root = create_treenode([4, 9, 0, 5, 1]) print(root) print('1',s.sumNumbers(root))
current_level.append(node.value) if node.left: q.append(node.left) if node.right: q.append(node.right) ret.append(current_level) return ret def levelOrder2(self, root): # dfs if not root: return [] def dfs(node, level): if not node: return if level > len(ret): ret.append([]) ret[level - 1].append(node.value) dfs(node.left, level + 1) dfs(node.right, level + 1) ret = [] dfs(root, 1) return ret if __name__ == '__main__': s = Solution() root = create_treenode([3, 9, 20, None, None, 15, 7]) print(root) print('1', s.levelOrder(root)) print('2', s.levelOrder2(root))
#O(n) if p.value < root.value > q.value: root = self.lowestCommonAncestor1(root.left, p, q) if p.value > root.value < q.value: root = self.lowestCommonAncestor1(root.right, p, q) return root def lowestCommonAncestor2(self, root, p, q): #O(n) while root: if p.value < root.value > q.value: root = root.left elif p.value > root.value < q.value: root = root.right else: return root if __name__ == "__main__": s = Solution() tree_node = create_treenode([6, 2, 8, 0, 4, 7, 9, None, None, 3, 5]) p = create_treenode([2, 8, 0, 4, 7, 9, None, None, 3, 5]) q = create_treenode([8, 0, 4, 7, 9, None, None, 3, 5]) print('1', s.lowestCommonAncestor1(tree_node, p, q).value) print('2', s.lowestCommonAncestor2(tree_node, p, q).value) tree_node = create_treenode([6, 2, 8, 0, 4, 7, 9, None, None, 3, 5]) p = create_treenode([2]) q = create_treenode([4]) print('1', s.lowestCommonAncestor1(tree_node, p, q).value) print('2', s.lowestCommonAncestor2(tree_node, p, q).value)
if not root: return [] #时间复杂度O(n) 空间复杂度O(n) import collections q = collections.deque([root]) ret = [] level = 1 while q: current_level = collections.deque() for _ in range(len(q)): node = q.popleft() if level & 1: current_level.append(node.value) else: current_level.appendleft(node.value) if node.left: q.append(node.left) if node.right: q.append(node.right) level += 1 ret.append(list(current_level)) return ret if __name__ == '__main__': s = Solution() root = create_treenode([3, 9, 20, None, None, 15, 7]) print('1', s.zigzagLevelOrder(root)) root = create_treenode([1, 2, 3, 4, None, None, 5]) print(root) print('1', s.zigzagLevelOrder(root)) # [[1],[3,2],[4,5]]
-1000 <= targetSum <= 1000 ''' class Solution: def hasPathSum(self, root, targetSum: int) -> bool: if not root:return False targetSum -=root.value if not root.left and not root.right and targetSum ==0: return True return self.hasPathSum(root.left, targetSum) or self.hasPathSum(root.right, targetSum) if __name__ == '__main__': s = Solution() from src.common.tree import create_treenode root = create_treenode( [5, 4, 8, 11, None, 13, 4, 7, 2, None, None, None, None, None, 1]) targetSum = 22 print(root) print('1', s.hasPathSum(root, targetSum)) root = create_treenode([1, 2, 3] ) targetSum = 5 print(root) print('1', s.hasPathSum(root, targetSum)) root = create_treenode([1, 2]) targetSum = 0 print(root) print('1', s.hasPathSum(root, targetSum))
-104 <= Node.val <= 104 ''' from src.common.tree import create_treenode class Solution: def isBalanced(self, root) -> bool: def height(root): if not root: return 0 nonlocal ret left_subtree_height = height(root.left) right_subtree_height = height(root.right) if abs(left_subtree_height - right_subtree_height) > 1: ret = False return max(left_subtree_height, right_subtree_height) + 1 ret = True height(root) return ret if __name__ == '__main__': s = Solution() root = [3, 9, 20, None, None, 15, 7] print('1', s.isBalanced(create_treenode(root))) root = [1, 2, 2, 3, 3, None, None, 4, 4] # print(create_treenode(root)) print('1', s.isBalanced(create_treenode(root))) root = [] print('1', s.isBalanced(create_treenode(root)))
3 6 / \ 2 4 / 1 输出: 4 限制: 1 ≤ k ≤ 二叉搜索树元素个数 ''' class Solution: def kthLargest(self, root, k: int) -> int: def inorder(node): if not node: return [] return inorder(node.left) + [node.value] + inorder(node.right) return inorder(root)[-k] if __name__ == '__main__': s = Solution() from src.common.tree import create_treenode root = create_treenode([3, 1, 4, None, 2]) k = 1 print(s.kthLargest(root, k)) root = create_treenode([5, 3, 6, 2, 4, None, None, 1]) k = 3 print(s.kthLargest(root, k))
node.right = Node(val) break else: node = node.right return root def insertIntoBST2(self, root, val: int): #递归 #世间法复杂度O(n) 空间复杂度O(n) if not root: return Node(val) if root.value < val: root.right = self.insertIntoBST2(root.right, val) else: root.left = self.insertIntoBST2(root.left, val) return root if __name__ == '__main__': s = Solution() root = create_treenode([4, 2, 7, 1, 3]) val = 5 print(root) print('1', s.insertIntoBST(root, val)) root = create_treenode([4, 2, 7, 1, 3]) print('2', s.insertIntoBST2(root, val)) root = create_treenode([40, 20, 60, 10, 30, 50, 70]) val = 25 print(root) print('1', s.insertIntoBST(root, val)) root = create_treenode([40, 20, 60, 10, 30, 50, 70]) print('2', s.insertIntoBST2(root, val))
q.append(a.left) q.append(b.right) q.append(a.right) q.append(b.left) return True def isSymmetric2(self, root) -> bool: if not root:return False def dfs(lnode,rnode): if not lnode and rnode:return False if not rnode and lnode:return False if not lnode and not rnode:return True return (lnode.value == rnode.value) and dfs(lnode.left, rnode.right) and dfs(lnode.right, rnode.left) return dfs(root.left,root.right) if __name__ =='__main__': s =Solution() root = create_treenode([1, 2, 2, 3, 4, 4, 3]) print(root) print('1',s.isSymmetric(root)) print('2',s.isSymmetric2(root)) root = create_treenode([1, 2, 2, None, 3, None, 3]) print(root) print('1',s.isSymmetric(root)) root = create_treenode([1, 2]) print(root) print('1',s.isSymmetric(root)) root = create_treenode( [2, 3, 3, 4, 5, 5, 4, None, None, 8, 9, None, None, 9, 8]) print(root) print('1',s.isSymmetric(root))
树中将会有 1 到 100 个结点。 ''' from src.common.tree import create_treenode class Solution: def isCompleteTree(self, root) -> bool: if not root: return False nodes = [(root, 1)] i = 0 while i < len(nodes): node, v = nodes[i] i += 1 if node.left: nodes.append((node.left, 2 * v)) if node.right: nodes.append((node.right, 2 * v + 1)) return nodes[-1][1] == len(nodes) if __name__ == '__main__': s = Solution() root = create_treenode([1, 2, 3]) print(root) print('1', s.isCompleteTree(root)) root = create_treenode([1, 2, 3, 4, 5, None, 7]) print(root) print('1', s.isCompleteTree(root))
进阶: 递归算法很简单,你可以通过迭代算法完成吗? ''' from src.common.tree import create_treenode class Solution: def postorderTraversal(self, root): if not root: return [] return self.postorderTraversal(root.left) + self.postorderTraversal( root.right) + [root.value] def postorderTraversal2(self, root): stack = [root] ret = [] while stack: node = stack.pop() if node: ret.append(node.value) stack.append(node.left) stack.append(node.right) return ret[::-1] if __name__ == '__main__': s = Solution() root = create_treenode([1, None, 2, None, None, 3]) print(root) print('1', s.postorderTraversal(root)) print('2', s.postorderTraversal2(root))
解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3 ''' class Solution: def binaryTreePaths(self, root): if not root: return [] def dfs(node, path): if not node: return path += str(node.value) if not node.left and not node.right: paths.append(path) else: path += '->' dfs(node.left, path) dfs(node.right, path) paths = [] dfs(root, '') return paths if __name__ == '__main__': s = Solution() from src.common.tree import create_treenode root = create_treenode([1, 2, 3, None, 5]) print(root) print('1', s.binaryTreePaths(root))
1 3 6 9 输出: 4 / \ 7 2 / \ / \ 9 6 3 1 备注: 这个问题是受到 Max Howell 的 原问题 启发的 : 谷歌:我们90%的工程师使用您编写的软件(Homebrew),但是您却无法在面试时在白板上写出翻转二叉树这道题,这太糟糕了。 ''' class Solution: def invertTree(self, root): if not root: return None left = self.invertTree(root.left) right = self.invertTree(root.right) root.left, root.right = right, left return root if __name__ == '__main__': s = Solution() from src.common.tree import create_treenode root = create_treenode([4, 2, 7, 1, 3, 6, 9]) print(root) print('1', s.invertTree(root))
node = q.popleft() if node.left: q.append(node.left) if node.right: q.append(node.right) return ret def rightSideView_dfs(self, root): if not root:return [] stack,ret =[(root,0)],dict() while stack: node,depth = stack.pop() if node: #setdefault已经存在的key,就不会重复插入 ret.setdefault(depth, node.value) stack.append((node.left,depth+1)) stack.append((node.right,depth+1)) return [val for _,val in ret.items()] if __name__ == '__main__': s = Solution() root = create_treenode([1, 2, 3, None, 5, None, 4]) print('bfs', s.rightSideView_bfs(root)) print('dfs', s.rightSideView_dfs(root)) # print('pre-order', root.preorder) root = create_treenode([1, 2]) print(root) print('bfs', s.rightSideView_bfs(root)) print('dfs', s.rightSideView_dfs(root))
示例 1: 输入:root = [3,9,20,null,null,15,7] 输出:2 示例 2: 输入:root = [2,null,3,null,4,null,5,null,6] 输出:5 ''' from src.common.tree import create_treenode class Solution: def minDepth(self, root) -> int: if not root: return 0 left_depth = self.minDepth(root.left) right_depth = self.minDepth(root.right) return left_depth + right_depth + 1 if ( left_depth == 0 or right_depth == 0) else min(left_depth, right_depth) + 1 def maxDepth(self, root) -> int: if not root: return 0 return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1 if __name__ == "__main__": s = Solution() l = [3, 9, 20, None, None, 15, 7] t = create_treenode(l) print(t) print('1', s.minDepth(t)) print('2', s.maxDepth(t))
class Solution: def longestUnivaluePath(self, root) -> int: def dfs(node): if not node: return 0 left_height = dfs(node.left) right_height = dfs(node.right) a, b = 0, 0 if node.left and node.value == node.left.value: a = left_height + 1 if node.right and node.value == node.right.value: b = right_height + 1 self.max_path = max(self.max_path, a + b) return max(a, b) self.max_path = 0 dfs(root) return self.max_path if __name__ == '__main__': s = Solution() root = create_treenode([5, 4, 5, 1, 1, None, 5]) print(root) print('1', s.longestUnivaluePath(root)) root = create_treenode([1, 4, 5, 4, 4, None, 5]) print(root) print('1', s.longestUnivaluePath(root))
return self.inorderTraversal( root.left) + [root.value] + self.inorderTraversal(root.right) def inorderTraversal2(self, root): stack = [] node = root ret = [] while stack or node: while node: stack.append(node) node = node.left if stack: node = stack.pop() ret.append(node.value) node = node.right return ret if __name__ == '__main__': s = Solution() root = create_treenode([1, None, 2, None, None, 3]) print('1', s.inorderTraversal(root)) root = create_treenode([]) print('1', s.inorderTraversal(root)) root = create_treenode([1, 2]) print('1', s.inorderTraversal(root)) root = create_treenode([1]) print('1', s.inorderTraversal(root)) root = create_treenode([1, None, 2]) print('1', s.inorderTraversal(root))
class Solution: def maxPathSum(self, root) -> int: def maxGain(node): if not node: return 0 left_gain = max(maxGain(node.left), 0) righ_gain = max(maxGain(node.right), 0) price_new_path = node.value + righ_gain + left_gain self.max_gain = max(self.max_gain, price_new_path) return node.value + max(left_gain, righ_gain) #时间复杂度O(n) 空间复杂度O(n) self.max_gain = float('-inf') maxGain(root) return self.max_gain if __name__ == '__main__': s = Solution() root = create_treenode([1, 2, 3]) print(root) print('1', s.maxPathSum(root)) root = create_treenode([-10, 9, 20, None, None, 15, 7]) print(root) print('1', s.maxPathSum(root)) root = create_treenode([-3]) print(root) print('1', s.maxPathSum(root))
return -1 elif node == target: subtree_add(node,0) return 1 else: l,r=dfs(node.left),dfs(node.right) if l !=-1: if l==K:ret.append(node.value) subtree_add(node.right,l+1) return l+1 elif r !=-1: if r == K: ret.append(node.value) subtree_add(node.left,r+1) return r+1 else: return -1 dfs(root) return ret if __name__ =='__main__': s = Solution() from src.common.tree import create_treenode root = create_treenode([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4]) target = root[1] K = 2 print(root,target) #[7, 4, 1] print('1', s.distanceK(root, target, K)) print('2', s.distanceK2(root, target, K))
def pathSum_dfs(self, root, targetSum: int): if not root: return [] # 时间复杂度O(n) 空间复杂度O(n) def dfs(root, targetSum): if not root: return path.append(root.value) targetSum -= root.value if not root.left and not root.right and targetSum == 0: ret.append(path[:]) dfs(root.left, targetSum) dfs(root.right, targetSum) path.pop() ret = [] path = [] dfs(root, targetSum) return ret if __name__ == '__main__': s = Solution() root = create_treenode( [5, 4, 8, 11, None, 13, 4, 7, 2, None, None, None, None, 5, 1]) print(root) ts = 22 print('1', s.pathSum_bfs(root, ts)) print('1', s.pathSum_dfs(root, ts))
class Solution: def preorderTraversal1(self, root): #递归 if not root: return [] l = self.preorderTraversal1(root.left) r = self.preorderTraversal1(root.right) return [root.value] + l + r def preorderTraversal2(self, root): #迭代 if not root: return [] stack, ret = [root], [] while stack: node = stack.pop() if node: ret.append(node.value) stack.append(node.right) stack.append(node.left) return ret if __name__ == '__main__': s = Solution() root = create_treenode([1, None, 2, None, None, 3]) print(root) print('1', s.preorderTraversal1(root)) print('2', s.preorderTraversal2(root)) root = create_treenode([1, 2, 3, 4, None, 5]) print('1', s.preorderTraversal1(root)) print('2', s.preorderTraversal2(root))
r_height = dfs(root.right) self.max_ret = max(self.max_ret, r_height + l_height + 1) return max(l_height, r_height) + 1 self.max_ret = 1 #最大节点数 dfs(root) return self.max_ret - 1 def diameterOfBinaryTree2(self, root) -> int: diameter = 0 def height(node): if not node: return 0 nonlocal diameter lheight = height(node.left) rheight = height(node.right) diameter = max(lheight + rheight, diameter) return max(lheight, rheight) + 1 height(root) return diameter if __name__ == '__main__': s = Solution() root = create_treenode([1, 2, 3, 4, 5]) print(root) print('1', s.diameterOfBinaryTree(root)) print('2', s.diameterOfBinaryTree2(root))
_, end = q[-1] for _ in range(len(q)): node, v = q.popleft() if node.left: q.append((node.left, 2 * v)) if node.right: q.append((node.right, 2 * v + 1)) print(q) max_width = max(max_width, end - start + 1) return max_width if __name__ == '__main__': s = Solution() from src.common.tree import create_treenode root = create_treenode([1, 3, 2, 5, 3, None, 9]) print(root) print('1', s.widthOfBinaryTree(root)) print('2', s.widthOfBinaryTree2(root)) root = create_treenode([1, 3, None, 5, 3]) print(root) print('1', s.widthOfBinaryTree(root)) print('2', s.widthOfBinaryTree2(root)) root = create_treenode([1, 3, 2, 5, None]) print(root) print('1', s.widthOfBinaryTree(root)) print('2', s.widthOfBinaryTree2(root)) root = create_treenode( [1, 3, 2, 5, None, None, 9, 6, None, None, None, None, None, None, 7]) print(root) print('1', s.widthOfBinaryTree(root))
def isValidBST4(self, root) -> bool: # 迭代中序遍历 stack = [] node = root inorder = float('-inf') #O(n*n) while stack or node: while node: stack.append(node) node = node.left node = stack.pop() if node.value <= inorder: return False inorder = node.value node = node.right return True if __name__ == "__main__": tree_node = create_treenode([2, 1, 3]) s = Solution() print('1', s.isValidBST1(tree_node)) print('2', s.isValidBST2(tree_node)) print('3', s.isValidBST3(tree_node)) print('4', s.isValidBST4(tree_node)) tree_node = create_treenode([5, 1, 4, None, None, 3, 6]) print('1', s.isValidBST1(tree_node)) print('2', s.isValidBST2(tree_node)) print('3', s.isValidBST3(tree_node)) print('4', s.isValidBST4(tree_node))