Solution) class Solution: def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: # res will be returned at the end # queue will save nodes level by level res, queue = [], deque() if root: queue.append(root) # Iterate tree while queue is not empty while queue: # This temporary list will save values of nodes in each level lv = [] # This for-loop will append the current level nodes' val..
Solution)class Solution: def rightSideView(self, root: Optional[TreeNode]) -> List[int]: # Base Case if not root: return None # queue will store nodes in each level # res will save values of nodes on the right side of tree queue, res = deque(), [] queue.append(root) while queue: # Append the value of nodes on the right side to res res.append(queue[0].val) for i in range(len(queue)): # Pop nodes ..
Solution) class Solution: def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': # Base Case if not root or root == p or root == q: return root # Recursive Call l = self.lowestCommonAncestor(root.left, p, q) r = self.lowestCommonAncestor(root.right, p, q) # If p and q are descendants of a certain node # return that node if l and r: return root # If p or q i..
Solution) class BSTIterator: def __init__(self, root: Optional[TreeNode]): # arr stores h nodes (h = height of the tree) self.arr = [] # Helper function adds nodes in root => leftmost leaf branch self.findNextNodes(root) def next(self) -> int: # nextNode is the smallest number node nextNode = self.arr.pop() # If nextNode has a right child, we add nodes from # right child => leftmost child to arr..
Solution)class Solution: def sumNumbers(self, root: Optional[TreeNode]) -> int: # res will save the sum of all root-to-leaf numbers res = 0 # finds root-to-leaf numbers and add them to res def helper(root, cur): # Base Case if not root: return # If leaf, add the current number to res if not root.left and not root.right: # Make sure to mark res as nonlocal for the # function to recognize nonlocal..
Solution)class Solution: def flatten(self, root: Optional[TreeNode]) -> None: # Base Case if not root: return # Initialization arr = [] # Helper func that adds nodes to arr in preorder def preorder(root): if not root: return None arr.append(root) preorder(root.left) preorder(root.right) preorder(root) # Connect nodes through right attribute cur = root for i in range(1, len(arr)): cur.left = None..
Solutionclass Solution: def connect(self, root: 'Node') -> 'Node': # Base Case if not root: return # Initialization parent, children = deque(), deque() parent.append(root) while parent: # Get the children of the nodes in a previous level while parent: cur = parent.popleft() if cur.left: children.append(cur.left) if cur.right: children.append(cur.right) # Connect the children through next attribu..
Solution)class Solution: def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]: # Base Case if not inorder or not postorder: return None # root is always the -1st element of postorder root = TreeNode(postorder[-1]) # Find the index of root in inorder mid = inorder.index(postorder[-1]) # Recursive Calls: # Adjust the ranges of left/right subtrees using mid root.left ..
Solution) class Solution: def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: # Base Case if not preorder or not inorder: return None # Root of a tree root = TreeNode(preorder[0]) # Index of root to distinguish left/right subtrees mid = inorder.index(preorder[0]) # Recursive calls to build left/right subtrees using mid root.left = self.buildTree(preorder[1:mid+1],..
Solution) # Doubly Linked List class ListNode: def __init__(self, key=0, val=0, nextt=None, prev=None): self.key = key self.val = val self.next = nextt self.prev = prev class LRUCache: def __init__(self, capacity: int): self.capacity = capacity self.storage = {} self.root = ListNode(0) self.tail = self.root def put(self, key: int, value: int) -> None: newNode = ListNode(key, value) self.append(n..