# CSPT 19 Lecture 10 ## [Max Depth](https://leetcode.com/problems/maximum-depth-of-binary-tree/) ``` from collections import deque class Solution: """ Plan Traverse the entire tree, while keeping track of the depth found for each node. Return the max depth found. Runtime: O(n) Space: O(n) """ def maxDepth(self, root: TreeNode) -> int: if root == None: return 0 self.maxDepth = 0 self.maxDepthHelper(root, 1) return self.maxDepth def maxDepthHelper(self, root, currDepth): # base-case if root.left == None and root.right == None: if currDepth > self.maxDepth: self.maxDepth = currDepth return # recursive-cases if root.left != None: self.maxDepthHelper(root.left, currDepth + 1) if root.right != None: self.maxDepthHelper(root.right, currDepth + 1) def iterativeMaxDepth(root): if root == None: return 0 queue = deque() queue.append((root, 1)) maxDepthFound = 1 while len(queue) > 0: curr = queue.popleft() currNode, currDepth = curr[0], curr[1] if currDepth > maxDepthFound: maxDepthFound = currDepth if currNode.left != None: queue.append((currNode.left, currDepth + 1)) if currNode.right != None: queue.append((currNode.right, currDepth + 1)) return maxDepthFound ``` ## [kth Smallest Element](https://leetcode.com/problems/kth-smallest-element-in-a-bst/) ``` class Solution: """ Plan 1. Traverse in an in-order traversal manner. Keep track of the number of node you visited. If k == numNodeVisited then return node.value 2. Traverse in an in-order manner. Push node's value into a list when it's time to process that node. In the end, you have a list of sorted values. Just index correctly to get the kth node's value """ # def kthSmallest(self, root: TreeNode, k: int) -> int: # res = [] # self.kthSmallestHelper(root, k, res) # return res[k - 1] # # Return the kth node's value OR None # def kthSmallestHelper(self, root, k, res): # # recursive-case 1 # if root.left != None: # self.kthSmallestHelper(root.left, k, res) # res.append(root.val) # # recursive case 2 # if root.right != None: # self.kthSmallestHelper(root.right, k, res) def kthSmallest(self, root: TreeNode, k: int) -> int: self.curr = 0 return self.kthSmallestHelper(root, k) # Return the kth node's value OR None def kthSmallestHelper(self, root, k): # recursive-case 1 if root.left != None: leftSubtree = self.kthSmallestHelper(root.left, k) if leftSubtree != None: return leftSubtree self.curr += 1 # base-case if self.curr == k: return root.val # recursive case 2 if root.right != None: rightSubtree = self.kthSmallestHelper(root.right, k) if rightSubtree != None: return rightSubtree return None ``` ## [Construct Tree]() ``` """ Understand preorder = [3,9,20,15,7] inorder = [9,3,15,20,7] 3 / \ 9 20 / \ 15 7 Plan Realize that the left part of the inorder array of a given node is its left subtree The right part of the inorder array is its right subtree Therefore, we can recreate the tree by going through each node in the preorder list and finding its index in the inorder list. We create that node and to recreate its subtrees, we recurse. Runtime: O(number of nodes) Space: O(number of nodes) """ def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode: return self.buildTreeHelper(deque(preorder), inorder, 0, len(inorder) - 1) def buildTreeHelper(self, preorder, inorder, inorderStartIndex, inorderEndIndex): if len(preorder) == 0 or inorderStartIndex > inorderEndIndex or inorderStartIndex < 0 or inorderEndIndex >= len(inorder): return None value = preorder.popleft() node = TreeNode(value) inorderIndex = inorder.index(value) node.left = self.buildTreeHelper(preorder, inorder, inorderStartIndex, inorderIndex - 1) node.right = self.buildTreeHelper(preorder, inorder, inorderIndex + 1, inorderEndIndex) return node ```