Showing 17 of 17 flashcards
Difficulty: EASY
LC: 110
Frequency: 48
Type: coding
Balanced Binary Tree — Return true if for every node |height(left)-height(right)| ≤ 1; e.g., [3,9,20,null,null,15,7] → true.
class Solution: def isBalanced(self, root: Optional[TreeNode]) -> bool: self.isBalanced=True def height_of_tree(node): if node is None: return 0 h_left=height_of_tree(node.left) h_right=height_of_tree(node.right) if abs(h_right-h_left)>1: self.isBalanced=False return 1+(max(h_left, h_right)) height_of_tree(root) return self.isBalanced
Trick: Custom Height of Tree function; At any point abs(L_H-R_H)>1: return False
Note: Done
Tags: Binary Tree
Difficulty: MEDIUM
LC: 102
Frequency: 52
Type: coding
Binary Tree Level Order Traversal — Return node values level-by-level from left to right; e.g., [3,9,20,null,null,15,7] → [[3],[9,20],[15,7]].
class Solution: def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: if not root: return [] q=deque([(root, 0)]) ans=[] while q: num_nodes=len(q) ans.append([]) for _ in range(num_nodes): node, level = q.popleft() ans[-1].append(node.val) if node.left: q.append((node.left, level+1)) if node.right: q.append((node.right, level+1)) return ans
Trick: BFS on Tree; num_nodes on level needs to be tracked; deque; can store (node, level) in deque if needed
Note: Done
Tags: Binary Tree
Difficulty: HARD
LC: 124
Frequency: 58
Type: coding
Binary Tree Maximum Path Sum — Return maximum sum of any path (can start/end anywhere, must follow parent-child edges); e.g., [-10,9,20,null,null,15,7] → 42 (15+20+7).
No answer provided.
Tags: Binary Tree
Difficulty: MEDIUM
LC: 199
Frequency: 53
Type: coding
Binary Tree Right Side View — Return rightmost value at each depth; e.g., [1,2,3,null,5,null,4] → [1,3,4].
class Solution: def rightSideView(self, root: Optional['TreeNode']) -> List[int]: """ Return the values visible from the right side of a binary tree. DFS: traverse right→left; record first node seen at each depth. """ view: List[int] = [] def dfs(node: Optional['TreeNode'], depth: int) -> None: if not node: return if depth == len(view): # first visit at this depth view.append(node.val) dfs(node.right, depth + 1) # right subtree first dfs(node.left, depth + 1) dfs(root, 0) return view
Trick: Explore right first; when new level found, rightmost element found; (Len(list)==level)** easy implementation with that trick
Note: Done
Tags: Binary Tree
Difficulty: MEDIUM
LC: 105
Frequency: 57
Type: coding
Construct Binary Tree from Preorder and Inorder Traversal — Rebuild the unique binary tree from preorder and inorder arrays; e.g., preorder=[3,9,20,15,7], inorder=[9,3,15,20,7] → [3,9,20,null,null,15,7].
class Solution: def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: if not preorder or not inorder: return None root_val=preorder[0] root=TreeNode(root_val) mid=inorder.index(root_val) root.left=self.buildTree(preorder[1:mid+1], inorder[:mid]) root.right=self.buildTree(preorder[mid+1:], inorder[mid+1:]) return root
Trick: Recursive Template; pre-order - you know the first node, calculate L and R on each side from inorder ; recurse on same function; Key-> draw diagram and L&R
Note: Done
Tags: Binary Tree
Difficulty: MEDIUM
LC: 1448
Frequency: 54
Type: coding
Count Good Nodes in Binary Tree — Count nodes that are ≥ all values on path from root to that node; e.g., [3,1,4,3,null,1,5] → 4.
class Solution: def goodNodes(self, root: TreeNode) -> int: def count_good_nodes(node, max_val): if not node: return 0 # A node is "good" if its value is greater than or equal to the maximum value seen so far. good = 1 if node.val >= max_val else 0 # Update max value seen so far max_val = max(max_val, node.val) # Recursively count good nodes in left and right subtrees good += count_good_nodes(node.left, max_val) good += count_good_nodes(node.right, max_val) return good return count_good_nodes(root, root.val)
Trick: DFS[max_val context]-recusion , BFS[Deque, with (node, max_so_far));
Note: Done
Tags: Binary Tree
Difficulty: MEDIUM
LC: 211
Frequency: 61
Type: coding
Design Add and Search Words Data Structure — Support addWord and search where '.' matches any letter; e.g., add "bad","dad","mad", search("b..") → true.
class TrieNode: def __init__(self): self.is_word = False self.children = {} class WordDictionary: def __init__(self): self.root = TrieNode() def addWord(self, word: str) -> None: curr = self.root for char in word: if char not in curr.children: curr.children[char] = TrieNode() curr = curr.children[char] curr.is_word = True # Mark the end of the word def _search_helper(self, word, node): curr = node for index, char in enumerate(word): if char == ".": for child in curr.children.values(): if self._search_helper(word[index + 1:], child): return True return False # No matches found if char not in curr.children: return False curr = curr.children[char] # Move to next character return curr.is_word # Check if it's a valid word def search(self, word: str) -> bool: return self._search_helper(word, self.root)
Trick: For "." -> search_helper(word, NODE) ; search(word[index+1:], child) for each child.
Note: Done
Tags: Trie
Difficulty: EASY
LC: 543
Frequency: 47
Type: coding
Diameter of Binary Tree — Return length in edges of longest path between any two nodes; e.g., [1,2,3,4,5] → 3.
class Solution: def diameterOfBinaryTree(self, root: Optional['TreeNode']) -> int: """ Post‑order DFS: for each node compute its subtree height. Diameter = max(left_height + right_height) over all nodes. """ if not root: return 0 diameter = 0 def dfs(node: Optional['TreeNode']) -> int: nonlocal diameter if not node: return 0 left_h = dfs(node.left) right_h = dfs(node.right) diameter = max(diameter, left_h + right_h) return 1 + max(left_h, right_h) dfs(root) return diameter
Trick: Simple height of tree custom function; nonlocal diameter
Note: Done
Tags: Binary Tree
Difficulty: MEDIUM
LC: 208
Frequency: 60
Type: coding
Implement Trie (Prefix Tree) — Support insert/search/startsWith for lowercase words efficiently; e.g., insert("apple"), search("app")=false, startsWith("app")=true.
class TrieNode: def __init__(self): self.is_word=False self.children={} class Trie: def __init__(self): self.root=TrieNode() def insert(self, word: str) -> None: curr=self.root for char in word: if char not in curr.children: curr.children[char]=TrieNode() curr=curr.children[char] curr.is_word=True def search(self, word: str) -> bool: curr=self.root for char in word: if char not in curr.children: return False curr=curr.children[char] return curr.is_word def startsWith(self, word: str) -> bool: curr=self.root for char in word: if char not in curr.children: return False curr=curr.children[char] return True
Trick: Standard Trie template; TrieNode: children={} is_word=""; insert(): curr=curr.children[char]
Note: Done
Tags: Trie
Difficulty: EASY
LC: 226
Frequency: 45
Type: coding
Invert Binary Tree — Swap left/right children at every node and return root; e.g., [4,2,7,1,3,6,9] → [4,7,2,9,6,3,1].
class Solution: def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]: if root is None: return root root.left, root.right = root.right, root.left self.invertTree(root.left) self.invertTree(root.right) return root
Trick: Simple; dont use temp, swap and recurse
Note: Done
Tags: Binary Tree
Difficulty: MEDIUM
LC: 230
Frequency: 56
Type: coding
Kth Smallest Element in a BST — Return the k-th smallest value in BST (1-indexed); e.g., [3,1,4,null,2], k=1 → 1.
class Solution: def kthSmallest(self, root: Optional[TreeNode], k: int) -> int: stack = [] while True: while root: stack.append(root) root = root.left root = stack.pop() k -= 1 if k==0: return root.val root = root.right
Trick: 1) Recusrive with global variables (easy) 2) Iterateive Inorder Traversal Template Using Stack;
Note: Done
Tags: Binary Tree
Difficulty: EASY
LC: 235
Frequency: 51
Type: coding
Lowest Common Ancestor of a Binary Search Tree — In BST, find lowest node whose value is between p and q (inclusive) so both are in its subtree; e.g., BST [6,2,8,0,4,7,9,3,5], p=2,q=8 → 6.
class Solution: def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': parent_val=root.val p_val=p.val q_val=q.val if parent_val>p_val and parent_val>q_val: return self.lowestCommonAncestor(root.left, p, q) elif parent_val<p_val and parent_val<q_val: return self.lowestCommonAncestor(root.right,p,q) else: return root
Trick: LCA exisits for sure, while getting back if p or q return and p&q return root; For BST: compare p & q with parent value; narrow to left or right or the node itself
Note: Done
Tags: Binary Tree
Difficulty: EASY
LC: 104
Frequency: 46
Type: coding
Maximum Depth of Binary Tree — Return number of nodes on longest root-to-leaf path; e.g., [3,9,20,null,null,15,7] → 3.
class Solution: def maxDepth(self, root: Optional[TreeNode]) -> int: if root is None: return 0 return 1+max(self.maxDepth(root.left), self.maxDepth(root.right))
Trick: 1 +max(depth_of_tree());
Note: Done
Tags: Binary Tree
Difficulty: EASY
LC: 100
Frequency: 49
Type: coding
Same Tree — Return true if two trees are structurally identical with same node values; e.g., [1,2,3] and [1,2,3] → true.
class Solution(object): def isSameTree(self, p, q): if p==None: return q==None if q==None: return p==None return p.val==q.val and self.isSameTree(p.left,q.left) and self.isSameTree(p.right,q.right)
Trick: Recursion/Check for Node and check for left and right
Note: Done
Tags: Binary Tree
Difficulty: HARD
LC: 297
Frequency: 59
Type: coding
Serialize and Deserialize Binary Tree — Design methods to convert a binary tree to a string and back preserving structure; e.g., serialize [1,2,3,null,null,4,5] then deserialize returns same tree.
class Codec: def serialize(self, root): """Encodes a tree to a single string. :type root: TreeNode :rtype: str """ self.tree=[] def dfs(node): if node == None: self.tree.append("X") return self.tree.append(str(node.val)) dfs(node.left) dfs(node.right) return dfs(root) return "#".join(self.tree) def deserialize(self, data): """ Decodes your encoded data to a tree. :type data: str :rtype: TreeNode """ def dfs(tree_iter): """ Helper function for depth-first search deserialization. """ val = next(tree_iter) if val == "X": return None node = TreeNode(int(val)) node.left = dfs(tree_iter) node.right = dfs(tree_iter) return node tree_iter = iter(data.split("#")) return dfs(tree_iter)
Trick: serialize-> Use "X" For None, "#" to join. deserialize -> Use deserial(iter(list.split(#)))
Note: Done
Tags: Binary Tree
Difficulty: EASY
LC: 572
Frequency: 50
Type: coding
Subtree of Another Tree — Return true if subRoot appears as an exact subtree of root (same structure/values); e.g., root=[3,4,5,1,2], subRoot=[4,1,2] → true.
class Solution: def isSubtree(self, s: TreeNode, t: TreeNode) -> bool: if not s: return False if self.isSameTree(s, t): return True return self.isSubtree(s.left, t) or self.isSubtree(s.right, t) def isSameTree(self, p: TreeNode, q: TreeNode) -> bool: if p and q: return p.val == q.val and self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) return p is q
Trick: For each node of S ; call is same tree
Note: Done
Tags: Binary Tree
Difficulty: MEDIUM
LC: 98
Frequency: 55
Type: coding
Validate Binary Search Tree — Return true if inorder is strictly increasing / left < node < right for all nodes; e.g., [2,1,3] → true, [5,1,4,null,null,3,6] → false.
class Solution: def isValidBST(self, root: Optional[TreeNode]) -> bool: return self.isValidTree(root, -float("inf"), float("inf")) def isValidTree(self, node, min_val, max_val): if node is None: return True if node.val<=min_val or node.val>=max_val: return False return self.isValidTree(node.left, min_val, node.val) and self.isValidTree(node.right, node.val, max_val)
Trick: isvalidTree(node, min_val=-float("inf"), float("inf")) -> check if node is valid and recurse
Note: Done
Tags: Binary Tree
We use cookies to improve your experience. By clicking “Accept” you consent to the use of cookies. Read our Privacy Policy.