From bd33583aa71c73fc2d39a91403a4c78779d54bed Mon Sep 17 00:00:00 2001 From: David Chen Date: Wed, 5 Nov 2025 07:13:48 -0800 Subject: [PATCH 1/7] added binary tree notes --- docs/notes/2025-11-05-binary-tree.md | 129 +++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 docs/notes/2025-11-05-binary-tree.md diff --git a/docs/notes/2025-11-05-binary-tree.md b/docs/notes/2025-11-05-binary-tree.md new file mode 100644 index 0000000..153b825 --- /dev/null +++ b/docs/notes/2025-11-05-binary-tree.md @@ -0,0 +1,129 @@ +# Binary Tree + +## Definition + +Binary Tree is a non-linear and hierarchical data structure where each node has at most two children referred to as the left child and the right child. + +## Structure + +### Example Binary Tree + +```mermaid +graph TD + id15((15)) + id35((35)) + id40((40)) + id3((3)) + id6((6)) + id5((5)) + id7((7)) + id1((1)) + id10((10)) + id8((8)) + id41((41)) + + id15 --- id35 + id15 --- id40 + id35 --- id3 + id35 --- id6 + id40 --- id5 + id40 --- id7 + id3 --- id1 + id3 --- id10 + id5 --- id8 + id5 --- id41 + + classDef internalNode fill:#D3D3D3,stroke:#333,stroke-width:1px,color:#000 + classDef leafNode fill:#90EE90,stroke:#333,stroke-width:1px,color:#000 + + class id15 internalNode + class id35 internalNode + class id40 internalNode + class id3 internalNode + class id6 internalNode + class id5 leafNode + class id7 leafNode + class id1 leafNode + class id10 leafNode + class id8 leafNode + class id41 leafNode +``` + +**Legend:** + +- Gray nodes = Internal nodes (nodes with at least one child) +- Green nodes = Leaf nodes (nodes with no children) + +**Tree Structure:** + +- Root: `15` +- Level 1: `35` (left child), `40` (right child) +- Level 2: `3` (left of 35), `6` (right of 35), `5` (left of 40), `7` (right of 40) +- Level 3: `1` (left of 3), `10` (right of 3), `8` (left of 5), `41` (right of 5) + +### Representation of a Binary Tree Node + +- Each node has 3 parts: + - Data + - Left Child + - Right Child + +```typescript +class TreeNode { + data: number; + left: TreeNode | null; + right: TreeNode | null; +} +``` + +### Terminology + +- **Root**: The topmost node in the tree +- **Parent Node**: A node that is the direct ancestor of a node(its child node) +- **Child Node**: A node that is the direct descendant of another node (its parent) +- **Ancestors of a node**: All nodes on the path from the root to that node (including the node itself) +- **Descendants of a node**: All nodes that lie in the subtree rooted at that node (including the node itself) +- **Subtree of a node**: A tree consisting of that node as root and all its descendants +- **Edge**: The link/connection between a parent node and its child node +- **Path in a binary tree**: A sequence of nodes connected by edges from one node to another +- **Leaf Node**: A node that does not have any children or both children are null +- **Internal Node**: A node that has at least one child +- **Depth/Level of a Node**: The number of edges in the path from root to that node (the depth/level of the root node is zero) +- **Height of a Binary Tree**: The number of edges on the longest path from root to a leaf + +### Properties of Binary Tree + +- The maximum number of nodes at level $i$ of a binary tree is $2^i$. +- The maximum number of nodes in a binary tree of height $h$ is $2^{h + 1} - 1$. +- Total number of leaf nodes = total number of nodes with 2 children + 1. +- The minimum height of a binary tree with $n$ nodes is $\log_2^n$. +- A binary tree with $L$ leaves has at least $\log_2^L + 1$ levels. + +## Operations on Binary Tree + +- **Insertion**: Insert a new node into the binary tree. +- **Deletion**: Delete a node from the binary tree. +- **Search**: Search for a node in the binary tree. +- **Traversal**: Traverse the binary tree. + +### Traversal of Binary Tree + +- **Breadth-first Traversal**: Visit the nodes level by level, from left to right. +- **Depth-first Traversal**: Visit the nodes depth by depth, from left to right. +- **Pre-order Traversal**: Visit the root node first, then the left subtree, then the right subtree. +- **In-order Traversal**: Visit the left subtree first, then the root node, then the right subtree. +- **Post-order Traversal**: Visit the left subtree first, then the right subtree, then the root node. + +## Advantages and Disadvantages of Binary Tree + +### Disadvantages + +- Limited structure +- Space inefficiency + +### Advantages + +- Represent hierarchical data +- Huffman Coding trees are used to compress data +- Useful for indexing segmented data and storing cache +- Useful for implementing decision trees, a type of machine learning algorithm for classification and regression analysis From 4dab448e8c5f9d999e5ac1b41951f648fa8dfe97 Mon Sep 17 00:00:00 2001 From: David Chen Date: Wed, 5 Nov 2025 09:51:17 -0800 Subject: [PATCH 2/7] added maximum depth of binary tree --- problems/0104-maximum-depth-of-binary-tree.ts | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 problems/0104-maximum-depth-of-binary-tree.ts diff --git a/problems/0104-maximum-depth-of-binary-tree.ts b/problems/0104-maximum-depth-of-binary-tree.ts new file mode 100644 index 0000000..c6c45c8 --- /dev/null +++ b/problems/0104-maximum-depth-of-binary-tree.ts @@ -0,0 +1,144 @@ +/** + * 0104. Maximum Depth of Binary Tree + * + * Difficulty: easy + * Tags: tree, depth-first-search, breadth-first-search, binary-tree + * + * Description: + * Given the `root` of a binary tree, return _its maximum depth_. + * + * A binary tree's **maximum depth** is the number of nodes along the longest path from the root node down to the farthest leaf node. + * + * Examples: + * 1. Input: root = \[1,null,2\] + * Output: 2 + * + * Constraints: + * - The number of nodes in the tree is in the range `[0, 10^4]`. + * - `-100 <= Node.val <= 100` + * + */ +import { z } from 'zod'; +import type { TestCase } from '../packages/src/types.js'; + +// export const TreeNodeSchema: z.ZodType = z.lazy(() => +// z.object({ +// val: z.number(), +// left: z.lazy(() => TreeNodeSchema).nullable(), +// right: z.lazy(() => TreeNodeSchema).nullable(), +// }) +// ); + +class TreeNode { + val: number; + left: TreeNode | null; + right: TreeNode | null; + constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + this.val = val ?? 0; + this.left = left ?? null; + this.right = right ?? null; + } +} + +export const TreeNodeSchema = z + .instanceof(TreeNode) + .check( + z.property('val', z.number()), + z.property('left', z.lazy(() => TreeNodeSchema).nullable()), + z.property('right', z.lazy(() => TreeNodeSchema).nullable()) + ); + +export const SolutionSchema = z.function({ + input: [TreeNodeSchema.nullable()], + output: z.number(), +}); + +export type Solution = z.infer; + +const arrayToTreeNode = (array: (number | null)[]): TreeNode => { + if (array.length === 0) { + throw new Error('Array is empty'); + } + const root = new TreeNode(array[0]!); + const queue: (TreeNode | null)[] = [root]; + + for (let index = 1; index < array.length + 1; index += 2) { + const node = queue.shift(); + if (node) { + node.left = array[index] ? new TreeNode(array[index]!) : null; + queue.push(node.left); + if (index + 1 < array.length) { + node.right = array[index + 1] ? new TreeNode(array[index + 1]!) : null; + queue.push(node.right); + } + } + } + return root; +}; + +export const cases: TestCase[] = [ + { + input: [arrayToTreeNode([3, 9, 20, null, null, 15, 7])], + expected: 3, + name: 'Example 1', + }, + { + input: [arrayToTreeNode([1, null, 2])], + expected: 2, + name: 'Example 2', + }, +]; + +/** + * Iterative Solution + * Approach: + * - Use a stack to traverse the tree iteratively + * - Track the current level and the maximum level + * - Return the maximum level + * Time Complexity: O(n) + * Space Complexity: O(h) where h is the height of the tree + */ +export const iterativeSolution = SolutionSchema.implement((root) => { + if (!root) { + return 0; + } + const stack: [TreeNode, number][] = [[root, 1]]; + let node: TreeNode | null = root; + let maxLevel = 0; + let currentLevel = 1; + while (stack.length > 0 || node !== null) { + while (node !== null) { + stack.push([node, currentLevel]); + node = node.left; + currentLevel += 1; + } + + const [currentNode, level] = stack.pop() as [TreeNode, number]; + maxLevel = Math.max(maxLevel, level); + + node = currentNode.right; + currentLevel = level + 1; + } + + return maxLevel; +}); + +/** + * Recursive Solution + * Approach: + * - Use a recursive function to traverse the tree + * - Return the maximum depth of the left and right subtrees + * - Return the maximum depth of the tree + * Time Complexity: O(n) + * Space Complexity: O(h) where h is the height of the tree + */ +export const recursiveSolution = SolutionSchema.implement((root) => { + if (!root) { + return 0; + } + return ( + 1 + Math.max(recursiveSolution(root.left), recursiveSolution(root.right)) + ); +}); + +export const solutions = [iterativeSolution, recursiveSolution]; From 48d11d2dff4e998840213deed0c3bd2f2e0f3c14 Mon Sep 17 00:00:00 2001 From: David Chen Date: Wed, 5 Nov 2025 14:17:46 -0800 Subject: [PATCH 3/7] added maximum depth of binary trees --- apps/site/src/data/index.json | 20 ++- .../src/data/problems/add-two-numbers.json | 6 +- .../site/src/data/problems/binary-search.json | 10 +- ...t-position-of-element-in-sorted-array.json | 12 +- .../src/data/problems/find-peak-element.json | 6 +- .../src/data/problems/first-bad-version.json | 14 +- .../guess-number-higher-or-lower.json | 6 +- ...ubstring-without-repeating-characters.json | 20 +-- .../maximum-depth-of-binary-tree.json | 152 ++++++++++++++++++ .../problems/median-of-two-sorted-arrays.json | 28 ++-- apps/site/src/data/problems/sqrt-x.json | 28 ++-- apps/site/src/data/problems/two-sum.json | 24 +-- .../src/data/problems/valid-parentheses.json | 10 +- packages/src/build-data.ts | 16 +- problems/0104-maximum-depth-of-binary-tree.ts | 4 +- 15 files changed, 268 insertions(+), 88 deletions(-) create mode 100644 apps/site/src/data/problems/maximum-depth-of-binary-tree.json diff --git a/apps/site/src/data/index.json b/apps/site/src/data/index.json index 3a49f2d..dd2b008 100644 --- a/apps/site/src/data/index.json +++ b/apps/site/src/data/index.json @@ -73,6 +73,18 @@ ], "difficulty": "easy" }, + { + "id": 104, + "slug": "maximum-depth-of-binary-tree", + "title": "Maximum Depth of Binary Tree", + "tags": [ + "tree", + "depth-first-search", + "breadth-first-search", + "binary-tree" + ], + "difficulty": "easy" + }, { "id": 162, "slug": "find-peak-element", @@ -114,9 +126,9 @@ "difficulty": "easy" } ], - "totalProblems": 11, + "totalProblems": 12, "difficultyCounts": { - "easy": 6, + "easy": 7, "medium": 4, "hard": 1 }, @@ -131,6 +143,10 @@ "binary-search": 7, "divide-and-conquer": 1, "stack": 1, + "tree": 1, + "depth-first-search": 1, + "breadth-first-search": 1, + "binary-tree": 1, "interactive": 2 } } \ No newline at end of file diff --git a/apps/site/src/data/problems/add-two-numbers.json b/apps/site/src/data/problems/add-two-numbers.json index c053740..52c995b 100644 --- a/apps/site/src/data/problems/add-two-numbers.json +++ b/apps/site/src/data/problems/add-two-numbers.json @@ -72,7 +72,7 @@ } }, "passed": true, - "duration": 0.29337500000008276 + "duration": 0.26400000000001 }, { "input": [ @@ -95,7 +95,7 @@ "next": null }, "passed": true, - "duration": 0.02333299999997962 + "duration": 0.019249999999999545 }, { "input": [ @@ -187,7 +187,7 @@ } }, "passed": true, - "duration": 0.019833999999946172 + "duration": 0.019958000000031006 } ], "totalTests": 3, diff --git a/apps/site/src/data/problems/binary-search.json b/apps/site/src/data/problems/binary-search.json index 64703ee..2258a41 100644 --- a/apps/site/src/data/problems/binary-search.json +++ b/apps/site/src/data/problems/binary-search.json @@ -33,7 +33,7 @@ "name": "Example 1", "actual": 4, "passed": true, - "duration": 0.04279199999996308 + "duration": 0.029374999999959073 }, { "input": [ @@ -51,7 +51,7 @@ "name": "Example 2", "actual": -1, "passed": true, - "duration": 0.003417000000013104 + "duration": 0.0060839999999871 }, { "input": [ @@ -69,7 +69,7 @@ "name": "Example 3", "actual": -1, "passed": true, - "duration": 0.0036659999999528736 + "duration": 0.0034999999999740794 }, { "input": [ @@ -87,7 +87,7 @@ "name": "Added negative number case", "actual": 0, "passed": true, - "duration": 0.006209000000012566 + "duration": 0.005457999999975982 }, { "input": [ @@ -105,7 +105,7 @@ "name": "Added positive number case", "actual": 5, "passed": true, - "duration": 0.002375000000029104 + "duration": 0.002541000000007898 } ], "totalTests": 5, diff --git a/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json b/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json index 0940f89..ece2364 100644 --- a/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json +++ b/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json @@ -39,7 +39,7 @@ 4 ], "passed": true, - "duration": 0.056500000000028194 + "duration": 0.047584000000028936 }, { "input": [ @@ -63,7 +63,7 @@ -1 ], "passed": true, - "duration": 0.0037919999999758147 + "duration": 0.004124999999987722 }, { "input": [ @@ -80,7 +80,7 @@ -1 ], "passed": true, - "duration": 0.0027499999999918145 + "duration": 0.0030409999999960746 }, { "input": [ @@ -108,7 +108,7 @@ 0 ], "passed": true, - "duration": 0.007000000000061846 + "duration": 0.003999999999962256 }, { "input": [ @@ -136,7 +136,7 @@ 9 ], "passed": true, - "duration": 0.009041999999908512 + "duration": 0.008249999999975444 }, { "input": [ @@ -156,7 +156,7 @@ 1 ], "passed": true, - "duration": 0.0024160000000392756 + "duration": 0.0024579999999900792 } ], "totalTests": 6, diff --git a/apps/site/src/data/problems/find-peak-element.json b/apps/site/src/data/problems/find-peak-element.json index ba23d05..dd91feb 100644 --- a/apps/site/src/data/problems/find-peak-element.json +++ b/apps/site/src/data/problems/find-peak-element.json @@ -30,7 +30,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.053167000000030384 + "duration": 0.03212500000000773 }, { "input": [ @@ -48,7 +48,7 @@ "name": "Example 2", "actual": 5, "passed": true, - "duration": 0.003291999999987638 + "duration": 0.0034160000000156288 }, { "input": [ @@ -61,7 +61,7 @@ "name": "Extended example 1", "actual": 1, "passed": true, - "duration": 0.0014999999999645297 + "duration": 0.001541000000031545 } ], "totalTests": 3, diff --git a/apps/site/src/data/problems/first-bad-version.json b/apps/site/src/data/problems/first-bad-version.json index 6589739..a1f47c4 100644 --- a/apps/site/src/data/problems/first-bad-version.json +++ b/apps/site/src/data/problems/first-bad-version.json @@ -26,7 +26,7 @@ "name": "Example 1", "actual": 1, "passed": true, - "duration": 0.07633299999997689 + "duration": 0.052666999999985364 }, { "input": [ @@ -37,7 +37,7 @@ "name": "Example 2", "actual": 1, "passed": true, - "duration": 0.004916999999977634 + "duration": 0.004500000000007276 }, { "input": [ @@ -48,7 +48,7 @@ "name": "Example 3", "actual": 2, "passed": true, - "duration": 0.0027090000000953296 + "duration": 0.002583000000015545 }, { "input": [ @@ -59,7 +59,7 @@ "name": "Example 4", "actual": 1, "passed": true, - "duration": 0.003125000000068212 + "duration": 0.0038329999999859865 }, { "input": [ @@ -70,7 +70,7 @@ "name": "Example 5", "actual": 4, "passed": true, - "duration": 0.00937500000009095 + "duration": 0.004666999999983545 }, { "input": [ @@ -81,7 +81,7 @@ "name": "Example 6", "actual": 4, "passed": true, - "duration": 0.003291999999987638 + "duration": 0.0029580000000350992 }, { "input": [ @@ -92,7 +92,7 @@ "name": "Example 7", "actual": 4, "passed": true, - "duration": 0.0017910000000256332 + "duration": 0.0043750000000386535 }, { "input": [ diff --git a/apps/site/src/data/problems/guess-number-higher-or-lower.json b/apps/site/src/data/problems/guess-number-higher-or-lower.json index 6dae89f..e28a2e0 100644 --- a/apps/site/src/data/problems/guess-number-higher-or-lower.json +++ b/apps/site/src/data/problems/guess-number-higher-or-lower.json @@ -26,7 +26,7 @@ "name": "Example 1", "actual": 6, "passed": true, - "duration": 0.06904099999997015 + "duration": 0.05370800000002873 }, { "input": [ @@ -37,7 +37,7 @@ "name": "Example 2", "actual": 1, "passed": true, - "duration": 0.004457999999999629 + "duration": 0.004082999999980075 }, { "input": [ @@ -48,7 +48,7 @@ "name": "Example 3", "actual": 1, "passed": true, - "duration": 0.0025000000000545697 + "duration": 0.002375000000029104 } ], "totalTests": 3, diff --git a/apps/site/src/data/problems/longest-substring-without-repeating-characters.json b/apps/site/src/data/problems/longest-substring-without-repeating-characters.json index b2199c4..a2d79fe 100644 --- a/apps/site/src/data/problems/longest-substring-without-repeating-characters.json +++ b/apps/site/src/data/problems/longest-substring-without-repeating-characters.json @@ -26,7 +26,7 @@ "name": "Example 1", "actual": 3, "passed": true, - "duration": 0.049250000000029104 + "duration": 0.03345799999999599 }, { "input": [ @@ -36,7 +36,7 @@ "name": "Example 2", "actual": 1, "passed": true, - "duration": 0.0030420000000503933 + "duration": 0.0044170000000463006 }, { "input": [ @@ -46,7 +46,7 @@ "name": "Example 3", "actual": 3, "passed": true, - "duration": 0.001958000000058746 + "duration": 0.002124999999978172 }, { "input": [ @@ -56,7 +56,7 @@ "name": "Example 4", "actual": 1, "passed": true, - "duration": 0.00100000000009004 + "duration": 0.0009169999999585343 }, { "input": [ @@ -66,7 +66,7 @@ "name": "Example 5", "actual": 2, "passed": true, - "duration": 0.00100000000009004 + "duration": 0.0009579999999687061 }, { "input": [ @@ -76,7 +76,7 @@ "name": "Example 6", "actual": 2, "passed": true, - "duration": 0.005667000000016742 + "duration": 0.001082999999994172 }, { "input": [ @@ -86,7 +86,7 @@ "name": "Example 7", "actual": 3, "passed": true, - "duration": 0.0012910000000374566 + "duration": 0.0012500000000272848 }, { "input": [ @@ -96,7 +96,7 @@ "name": "Example 8", "actual": 3, "passed": true, - "duration": 0.001209000000017113 + "duration": 0.0012080000000196378 }, { "input": [ @@ -106,7 +106,7 @@ "name": "Example 9", "actual": 3, "passed": true, - "duration": 0.0018330000000332802 + "duration": 0.0017500000000154614 }, { "input": [ @@ -116,7 +116,7 @@ "name": "Example 10", "actual": 5, "passed": true, - "duration": 0.0020419999999603533 + "duration": 0.0019580000000019027 } ], "totalTests": 10, diff --git a/apps/site/src/data/problems/maximum-depth-of-binary-tree.json b/apps/site/src/data/problems/maximum-depth-of-binary-tree.json new file mode 100644 index 0000000..4581db0 --- /dev/null +++ b/apps/site/src/data/problems/maximum-depth-of-binary-tree.json @@ -0,0 +1,152 @@ +{ + "id": 104, + "slug": "maximum-depth-of-binary-tree", + "title": "Maximum Depth of Binary Tree", + "tags": [ + "tree", + "depth-first-search", + "breadth-first-search", + "binary-tree" + ], + "difficulty": "easy", + "solutions": [ + { + "name": "iterativeSolution", + "description": "", + "approach": "- Use a stack to traverse the tree iteratively\n - Track the current level and the maximum level\n - Return the maximum level", + "timeComplexity": "O(n)", + "spaceComplexity": "O(h) where h is the height of the tree", + "code": "
const iterativeSolution = (root) => {\n  if (!root) {\n    return 0;\n  }\n  const stack: [TreeNode, number][] = [[root, 1]];\n  let node: TreeNode | null = root;\n  let maxLevel = 0;\n  let currentLevel = 1;\n  while (stack.length > 0 || node !== null) {\n    while (node !== null) {\n      stack.push([node, currentLevel]);\n      node = node.left;\n      currentLevel += 1;\n    }\n\n    const [currentNode, level] = stack.pop() as [TreeNode, number];\n    maxLevel = Math.max(maxLevel, level);\n\n    node = currentNode.right;\n    currentLevel = level + 1;\n  }\n\n  return maxLevel;\n};\n
", + "utilities": [ + { + "name": "TreeNode", + "code": "
class TreeNode {\n  val: number;\n  left: TreeNode | null;\n  right: TreeNode | null;\n  constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {\n    this.val = val ?? 0;\n    this.left = left ?? null;\n    this.right = right ?? null;\n  }\n
" + } + ], + "testResults": [ + { + "input": [ + { + "val": 3, + "left": { + "val": 9, + "left": null, + "right": null + }, + "right": { + "val": 20, + "left": { + "val": 15, + "left": null, + "right": null + }, + "right": { + "val": 7, + "left": null, + "right": null + } + } + } + ], + "expected": 3, + "name": "Example 1", + "actual": 3, + "passed": true, + "duration": 0.27191699999997354 + }, + { + "input": [ + { + "val": 1, + "left": null, + "right": { + "val": 2, + "left": null, + "right": null + } + } + ], + "expected": 2, + "name": "Example 2", + "actual": 2, + "passed": true, + "duration": 0.013958999999999833 + } + ], + "totalTests": 2, + "passedTests": 2, + "failedTests": 0 + }, + { + "name": "recursiveSolution", + "description": "", + "approach": "- Use a recursive function to traverse the tree\n - Return the maximum depth of the left and right subtrees\n - Return the maximum depth of the tree", + "timeComplexity": "O(n)", + "spaceComplexity": "O(h) where h is the height of the tree", + "code": "
const recursiveSolution = (root) => {\n  if (!root) {\n    return 0;\n  }\n  return (\n    1 + Math.max(recursiveSolution(root.left), recursiveSolution(root.right))\n  );\n};\n
", + "utilities": [ + { + "name": "TreeNode", + "code": "
class TreeNode {\n  val: number;\n  left: TreeNode | null;\n  right: TreeNode | null;\n  constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {\n    this.val = val ?? 0;\n    this.left = left ?? null;\n    this.right = right ?? null;\n  }\n
" + } + ], + "testResults": [ + { + "input": [ + { + "val": 3, + "left": { + "val": 9, + "left": null, + "right": null + }, + "right": { + "val": 20, + "left": { + "val": 15, + "left": null, + "right": null + }, + "right": { + "val": 7, + "left": null, + "right": null + } + } + } + ], + "expected": 3, + "name": "Example 1", + "actual": 3, + "passed": true, + "duration": 0.08625000000000682 + }, + { + "input": [ + { + "val": 1, + "left": null, + "right": { + "val": 2, + "left": null, + "right": null + } + } + ], + "expected": 2, + "name": "Example 2", + "actual": 2, + "passed": true, + "duration": 0.007040999999958331 + } + ], + "totalTests": 2, + "passedTests": 2, + "failedTests": 0 + } + ], + "notes": "
    \n
    1. \n
    2. Maximum Depth of Binary Tree
    3. \n
    \n
  • \n
  • \n
  • Difficulty: easy
  • \n
  • Tags: tree, depth-first-search, breadth-first-search, binary-tree
  • \n
  • \n
  • Description:
  • \n
  • Given the root of a binary tree, return its maximum depth.
  • \n
  • \n
  • A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
  • \n
  • \n
  • Examples:
  • \n
    1. \n
    2. Input: root = [1,null,2]
    3. \n
    \n
  • \n
  • Output: 2
  • \n
  • \n
  • Constraints:
  • \n
    • \n
    • The number of nodes in the tree is in the range [0, 10^4].
    • \n
    \n
  • \n
    • \n
    • -100 <= Node.val <= 100
    • \n
    \n
  • \n
  • \n
\n", + "totalTests": 4, + "passedTests": 4, + "failedTests": 0 +} \ No newline at end of file diff --git a/apps/site/src/data/problems/median-of-two-sorted-arrays.json b/apps/site/src/data/problems/median-of-two-sorted-arrays.json index 274a4fe..0e80091 100644 --- a/apps/site/src/data/problems/median-of-two-sorted-arrays.json +++ b/apps/site/src/data/problems/median-of-two-sorted-arrays.json @@ -32,7 +32,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.06529199999999946 + "duration": 0.052957999999989624 }, { "input": [ @@ -49,7 +49,7 @@ "name": "Example 2", "actual": 2.5, "passed": true, - "duration": 0.006499999999959982 + "duration": 0.006250000000022737 }, { "input": [ @@ -66,7 +66,7 @@ "name": "Extended Example 1", "actual": 0, "passed": true, - "duration": 0.005583000000001448 + "duration": 0.002874999999960437 }, { "input": [ @@ -79,7 +79,7 @@ "name": "Extended Example 2", "actual": 1, "passed": true, - "duration": 0.002375000000029104 + "duration": 0.002207999999995991 }, { "input": [ @@ -92,7 +92,7 @@ "name": "Extended Example 3", "actual": 2, "passed": true, - "duration": 0.002124999999978172 + "duration": 0.0020000000000095497 }, { "input": [ @@ -115,7 +115,7 @@ "name": "Extended Example 4", "actual": 5.5, "passed": true, - "duration": 0.0041669999999385254 + "duration": 0.005000000000052296 }, { "input": [ @@ -132,7 +132,7 @@ "name": "Extended Example 5", "actual": 3, "passed": true, - "duration": 0.04891699999996035 + "duration": 0.04820799999998826 } ], "totalTests": 7, @@ -162,7 +162,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.02895899999998619 + "duration": 0.025040999999987434 }, { "input": [ @@ -179,7 +179,7 @@ "name": "Example 2", "actual": 2.5, "passed": true, - "duration": 0.003917000000001281 + "duration": 0.0036249999999995453 }, { "input": [ @@ -196,7 +196,7 @@ "name": "Extended Example 1", "actual": 0, "passed": true, - "duration": 0.0038329999999859865 + "duration": 0.0042910000000233595 }, { "input": [ @@ -209,7 +209,7 @@ "name": "Extended Example 2", "actual": 1, "passed": true, - "duration": 0.002040999999962878 + "duration": 0.0018329999999764368 }, { "input": [ @@ -222,7 +222,7 @@ "name": "Extended Example 3", "actual": 2, "passed": true, - "duration": 0.0052090000000362124 + "duration": 0.002082999999970525 }, { "input": [ @@ -245,7 +245,7 @@ "name": "Extended Example 4", "actual": 5.5, "passed": true, - "duration": 0.009958999999980733 + "duration": 0.007999999999981355 }, { "input": [ @@ -262,7 +262,7 @@ "name": "Extended Example 5", "actual": 3, "passed": true, - "duration": 0.0027919999999994616 + "duration": 0.002708000000041011 } ], "totalTests": 7, diff --git a/apps/site/src/data/problems/sqrt-x.json b/apps/site/src/data/problems/sqrt-x.json index 289afa5..c81d974 100644 --- a/apps/site/src/data/problems/sqrt-x.json +++ b/apps/site/src/data/problems/sqrt-x.json @@ -25,7 +25,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.04399999999998272 + "duration": 0.032083000000000084 }, { "input": [ @@ -35,7 +35,7 @@ "name": "Example 2", "actual": 2, "passed": true, - "duration": 0.003207999999972344 + "duration": 0.0027919999999994616 }, { "input": [ @@ -45,7 +45,7 @@ "name": "Extended Example 1", "actual": 4, "passed": true, - "duration": 0.0014169999999467109 + "duration": 0.001416000000006079 }, { "input": [ @@ -55,7 +55,7 @@ "name": "Extended Example 2", "actual": 5, "passed": true, - "duration": 0.001125000000001819 + "duration": 0.0010420000000408436 }, { "input": [ @@ -65,7 +65,7 @@ "name": "Extended Example 3", "actual": 0, "passed": true, - "duration": 0.07929100000001199 + "duration": 0.0578750000000241 }, { "input": [ @@ -75,7 +75,7 @@ "name": "Extended Example 4", "actual": 3, "passed": true, - "duration": 0.003249999999979991 + "duration": 0.0028750000000172804 }, { "input": [ @@ -95,7 +95,7 @@ "name": "Extended Example 6", "actual": 1, "passed": true, - "duration": 0.0008749999999508873 + "duration": 0.0008339999999975589 } ], "totalTests": 8, @@ -119,7 +119,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.017416000000025633 + "duration": 0.01541599999995924 }, { "input": [ @@ -129,7 +129,7 @@ "name": "Example 2", "actual": 2, "passed": true, - "duration": 0.0014170000000603977 + "duration": 0.0015000000000213731 }, { "input": [ @@ -139,7 +139,7 @@ "name": "Extended Example 1", "actual": 4, "passed": true, - "duration": 0.003040999999939231 + "duration": 0.002667000000030839 }, { "input": [ @@ -149,7 +149,7 @@ "name": "Extended Example 2", "actual": 5, "passed": true, - "duration": 0.0013749999999390639 + "duration": 0.0013749999999959073 }, { "input": [ @@ -159,7 +159,7 @@ "name": "Extended Example 3", "actual": 0, "passed": true, - "duration": 0.0008750000000645741 + "duration": 0.0008330000000000837 }, { "input": [ @@ -179,7 +179,7 @@ "name": "Extended Example 5", "actual": 1, "passed": true, - "duration": 0.0009579999999687061 + "duration": 0.0009999999999763531 }, { "input": [ @@ -189,7 +189,7 @@ "name": "Extended Example 6", "actual": 1, "passed": true, - "duration": 0.0008750000000645741 + "duration": 0.0007919999999899119 } ], "totalTests": 8, diff --git a/apps/site/src/data/problems/two-sum.json b/apps/site/src/data/problems/two-sum.json index 54a5322..69e19d5 100644 --- a/apps/site/src/data/problems/two-sum.json +++ b/apps/site/src/data/problems/two-sum.json @@ -37,7 +37,7 @@ 1 ], "passed": true, - "duration": 0.15195799999992232 + "duration": 0.15954200000004448 }, { "input": [ @@ -58,7 +58,7 @@ 2 ], "passed": true, - "duration": 0.09183299999995143 + "duration": 0.08816699999999855 }, { "input": [ @@ -78,7 +78,7 @@ 1 ], "passed": true, - "duration": 0.011249999999904503 + "duration": 0.01245899999997846 }, { "input": [ @@ -106,7 +106,7 @@ 9 ], "passed": true, - "duration": 0.013832999999976892 + "duration": 0.016416999999989912 }, { "input": [ @@ -134,7 +134,7 @@ 9 ], "passed": true, - "duration": 0.010708000000022366 + "duration": 0.01191700000003948 }, { "input": [ @@ -162,7 +162,7 @@ 1 ], "passed": true, - "duration": 0.06795899999997346 + "duration": 0.06370800000001964 } ], "totalTests": 6, @@ -198,7 +198,7 @@ 1 ], "passed": true, - "duration": 0.05320799999992687 + "duration": 0.04870799999997644 }, { "input": [ @@ -219,7 +219,7 @@ 2 ], "passed": true, - "duration": 0.004125000000044565 + "duration": 0.004250000000013188 }, { "input": [ @@ -239,7 +239,7 @@ 1 ], "passed": true, - "duration": 0.003458000000023276 + "duration": 0.004916999999977634 }, { "input": [ @@ -267,7 +267,7 @@ 9 ], "passed": true, - "duration": 0.008832999999981439 + "duration": 0.009833000000014636 }, { "input": [ @@ -295,7 +295,7 @@ 9 ], "passed": true, - "duration": 0.005457999999975982 + "duration": 0.005875000000003183 }, { "input": [ @@ -323,7 +323,7 @@ 1 ], "passed": true, - "duration": 0.006499999999959982 + "duration": 0.00637499999999136 } ], "totalTests": 6, diff --git a/apps/site/src/data/problems/valid-parentheses.json b/apps/site/src/data/problems/valid-parentheses.json index 4be0df2..eca29a8 100644 --- a/apps/site/src/data/problems/valid-parentheses.json +++ b/apps/site/src/data/problems/valid-parentheses.json @@ -25,7 +25,7 @@ "name": "Example 1", "actual": true, "passed": true, - "duration": 0.05670799999995779 + "duration": 0.06974999999999909 }, { "input": [ @@ -35,7 +35,7 @@ "name": "Example 2", "actual": true, "passed": true, - "duration": 0.00483299999996234 + "duration": 0.005667000000016742 }, { "input": [ @@ -45,7 +45,7 @@ "name": "Example 3", "actual": false, "passed": true, - "duration": 0.00541699999996581 + "duration": 0.006832999999971889 }, { "input": [ @@ -55,7 +55,7 @@ "name": "Example 4", "actual": true, "passed": true, - "duration": 0.0037499999999681677 + "duration": 0.004540999999960604 }, { "input": [ @@ -65,7 +65,7 @@ "name": "Example 5", "actual": false, "passed": true, - "duration": 0.0032089999999698193 + "duration": 0.0015829999999823485 } ], "totalTests": 5, diff --git a/packages/src/build-data.ts b/packages/src/build-data.ts index a105f7c..faa8651 100644 --- a/packages/src/build-data.ts +++ b/packages/src/build-data.ts @@ -265,6 +265,16 @@ function extractUtilityDefinition( result = `const ${utilityName}: z.ZodType = ${zodMatch[1].trim()};`; } + // Try to find class definitions + const classRegex = new RegExp( + `export\\s+class\\s+${utilityName}\\s*\\{([\\s\\S]*?)\\}\\s*`, + 'g' + ); + const classMatch = classRegex.exec(sourceContent); + if (classMatch) { + result = `class ${utilityName} {${classMatch[1]}}`; + } + return result; } @@ -591,9 +601,9 @@ async function extractCodeAndNotes( // Process markdown to HTML const notes = cleanedNotes ? await marked.parse(cleanedNotes, { - breaks: true, - gfm: true, - }) + breaks: true, + gfm: true, + }) : ''; // For the new format, we don't need to extract code here since diff --git a/problems/0104-maximum-depth-of-binary-tree.ts b/problems/0104-maximum-depth-of-binary-tree.ts index c6c45c8..2bde2e2 100644 --- a/problems/0104-maximum-depth-of-binary-tree.ts +++ b/problems/0104-maximum-depth-of-binary-tree.ts @@ -29,7 +29,7 @@ import type { TestCase } from '../packages/src/types.js'; // }) // ); -class TreeNode { +export class TreeNode { val: number; left: TreeNode | null; right: TreeNode | null; @@ -91,6 +91,7 @@ export const cases: TestCase[] = [ /** * Iterative Solution + * @utilities: TreeNode * Approach: * - Use a stack to traverse the tree iteratively * - Track the current level and the maximum level @@ -125,6 +126,7 @@ export const iterativeSolution = SolutionSchema.implement((root) => { /** * Recursive Solution + * @utilities: TreeNode * Approach: * - Use a recursive function to traverse the tree * - Return the maximum depth of the left and right subtrees From e96a340649694fe6f81b734d9f1e960a0e5f157f Mon Sep 17 00:00:00 2001 From: David Chen Date: Wed, 5 Nov 2025 14:36:45 -0800 Subject: [PATCH 4/7] fix example grep --- .../src/data/problems/add-two-numbers.json | 6 +- .../site/src/data/problems/binary-search.json | 10 +- ...t-position-of-element-in-sorted-array.json | 12 +- .../src/data/problems/find-peak-element.json | 6 +- .../src/data/problems/first-bad-version.json | 16 +- .../guess-number-higher-or-lower.json | 6 +- ...ubstring-without-repeating-characters.json | 20 +-- .../maximum-depth-of-binary-tree.json | 10 +- .../problems/median-of-two-sorted-arrays.json | 28 ++-- apps/site/src/data/problems/sqrt-x.json | 30 ++-- apps/site/src/data/problems/two-sum.json | 24 +-- .../src/data/problems/valid-parentheses.json | 10 +- packages/src/leetcode-scraper.ts | 154 +++++++++++++----- problems/0104-maximum-depth-of-binary-tree.ts | 12 +- 14 files changed, 208 insertions(+), 136 deletions(-) diff --git a/apps/site/src/data/problems/add-two-numbers.json b/apps/site/src/data/problems/add-two-numbers.json index 52c995b..b5f84e9 100644 --- a/apps/site/src/data/problems/add-two-numbers.json +++ b/apps/site/src/data/problems/add-two-numbers.json @@ -72,7 +72,7 @@ } }, "passed": true, - "duration": 0.26400000000001 + "duration": 0.3231249999999477 }, { "input": [ @@ -95,7 +95,7 @@ "next": null }, "passed": true, - "duration": 0.019249999999999545 + "duration": 0.02312499999999318 }, { "input": [ @@ -187,7 +187,7 @@ } }, "passed": true, - "duration": 0.019958000000031006 + "duration": 0.020582999999987805 } ], "totalTests": 3, diff --git a/apps/site/src/data/problems/binary-search.json b/apps/site/src/data/problems/binary-search.json index 2258a41..32a20eb 100644 --- a/apps/site/src/data/problems/binary-search.json +++ b/apps/site/src/data/problems/binary-search.json @@ -33,7 +33,7 @@ "name": "Example 1", "actual": 4, "passed": true, - "duration": 0.029374999999959073 + "duration": 0.043083000000024185 }, { "input": [ @@ -51,7 +51,7 @@ "name": "Example 2", "actual": -1, "passed": true, - "duration": 0.0060839999999871 + "duration": 0.003957999999954609 }, { "input": [ @@ -69,7 +69,7 @@ "name": "Example 3", "actual": -1, "passed": true, - "duration": 0.0034999999999740794 + "duration": 0.003959000000008928 }, { "input": [ @@ -87,7 +87,7 @@ "name": "Added negative number case", "actual": 0, "passed": true, - "duration": 0.005457999999975982 + "duration": 0.00637499999999136 }, { "input": [ @@ -105,7 +105,7 @@ "name": "Added positive number case", "actual": 5, "passed": true, - "duration": 0.002541000000007898 + "duration": 0.002583000000015545 } ], "totalTests": 5, diff --git a/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json b/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json index ece2364..67ac6d9 100644 --- a/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json +++ b/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json @@ -39,7 +39,7 @@ 4 ], "passed": true, - "duration": 0.047584000000028936 + "duration": 0.05133299999999963 }, { "input": [ @@ -63,7 +63,7 @@ -1 ], "passed": true, - "duration": 0.004124999999987722 + "duration": 0.004083000000036918 }, { "input": [ @@ -80,7 +80,7 @@ -1 ], "passed": true, - "duration": 0.0030409999999960746 + "duration": 0.0027499999999918145 }, { "input": [ @@ -108,7 +108,7 @@ 0 ], "passed": true, - "duration": 0.003999999999962256 + "duration": 0.004000000000019099 }, { "input": [ @@ -136,7 +136,7 @@ 9 ], "passed": true, - "duration": 0.008249999999975444 + "duration": 0.009375000000034106 }, { "input": [ @@ -156,7 +156,7 @@ 1 ], "passed": true, - "duration": 0.0024579999999900792 + "duration": 0.002417000000036751 } ], "totalTests": 6, diff --git a/apps/site/src/data/problems/find-peak-element.json b/apps/site/src/data/problems/find-peak-element.json index dd91feb..d6621ce 100644 --- a/apps/site/src/data/problems/find-peak-element.json +++ b/apps/site/src/data/problems/find-peak-element.json @@ -30,7 +30,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.03212500000000773 + "duration": 0.04762500000003911 }, { "input": [ @@ -48,7 +48,7 @@ "name": "Example 2", "actual": 5, "passed": true, - "duration": 0.0034160000000156288 + "duration": 0.003458000000023276 }, { "input": [ @@ -61,7 +61,7 @@ "name": "Extended example 1", "actual": 1, "passed": true, - "duration": 0.001541000000031545 + "duration": 0.0015839999999798238 } ], "totalTests": 3, diff --git a/apps/site/src/data/problems/first-bad-version.json b/apps/site/src/data/problems/first-bad-version.json index a1f47c4..8fc3c1b 100644 --- a/apps/site/src/data/problems/first-bad-version.json +++ b/apps/site/src/data/problems/first-bad-version.json @@ -26,7 +26,7 @@ "name": "Example 1", "actual": 1, "passed": true, - "duration": 0.052666999999985364 + "duration": 0.07362499999999272 }, { "input": [ @@ -37,7 +37,7 @@ "name": "Example 2", "actual": 1, "passed": true, - "duration": 0.004500000000007276 + "duration": 0.005083000000013271 }, { "input": [ @@ -48,7 +48,7 @@ "name": "Example 3", "actual": 2, "passed": true, - "duration": 0.002583000000015545 + "duration": 0.002625000000023192 }, { "input": [ @@ -59,7 +59,7 @@ "name": "Example 4", "actual": 1, "passed": true, - "duration": 0.0038329999999859865 + "duration": 0.003666000000009717 }, { "input": [ @@ -70,7 +70,7 @@ "name": "Example 5", "actual": 4, "passed": true, - "duration": 0.004666999999983545 + "duration": 0.005207999999981894 }, { "input": [ @@ -81,7 +81,7 @@ "name": "Example 6", "actual": 4, "passed": true, - "duration": 0.0029580000000350992 + "duration": 0.0032500000000368345 }, { "input": [ @@ -92,7 +92,7 @@ "name": "Example 7", "actual": 4, "passed": true, - "duration": 0.0043750000000386535 + "duration": 0.0018330000000332802 }, { "input": [ @@ -103,7 +103,7 @@ "name": "Example 8", "actual": 4, "passed": true, - "duration": 0.0017500000000154614 + "duration": 0.0017920000000231084 } ], "totalTests": 8, diff --git a/apps/site/src/data/problems/guess-number-higher-or-lower.json b/apps/site/src/data/problems/guess-number-higher-or-lower.json index e28a2e0..6a48fd2 100644 --- a/apps/site/src/data/problems/guess-number-higher-or-lower.json +++ b/apps/site/src/data/problems/guess-number-higher-or-lower.json @@ -26,7 +26,7 @@ "name": "Example 1", "actual": 6, "passed": true, - "duration": 0.05370800000002873 + "duration": 0.07783299999999826 }, { "input": [ @@ -37,7 +37,7 @@ "name": "Example 2", "actual": 1, "passed": true, - "duration": 0.004082999999980075 + "duration": 0.004667000000040389 }, { "input": [ @@ -48,7 +48,7 @@ "name": "Example 3", "actual": 1, "passed": true, - "duration": 0.002375000000029104 + "duration": 0.0025420000000053733 } ], "totalTests": 3, diff --git a/apps/site/src/data/problems/longest-substring-without-repeating-characters.json b/apps/site/src/data/problems/longest-substring-without-repeating-characters.json index a2d79fe..bcf8636 100644 --- a/apps/site/src/data/problems/longest-substring-without-repeating-characters.json +++ b/apps/site/src/data/problems/longest-substring-without-repeating-characters.json @@ -26,7 +26,7 @@ "name": "Example 1", "actual": 3, "passed": true, - "duration": 0.03345799999999599 + "duration": 0.0504579999999919 }, { "input": [ @@ -36,7 +36,7 @@ "name": "Example 2", "actual": 1, "passed": true, - "duration": 0.0044170000000463006 + "duration": 0.0031670000000190157 }, { "input": [ @@ -46,7 +46,7 @@ "name": "Example 3", "actual": 3, "passed": true, - "duration": 0.002124999999978172 + "duration": 0.002165999999988344 }, { "input": [ @@ -56,7 +56,7 @@ "name": "Example 4", "actual": 1, "passed": true, - "duration": 0.0009169999999585343 + "duration": 0.001167000000009466 }, { "input": [ @@ -66,7 +66,7 @@ "name": "Example 5", "actual": 2, "passed": true, - "duration": 0.0009579999999687061 + "duration": 0.0010420000000408436 }, { "input": [ @@ -76,7 +76,7 @@ "name": "Example 6", "actual": 2, "passed": true, - "duration": 0.001082999999994172 + "duration": 0.0012910000000374566 }, { "input": [ @@ -86,7 +86,7 @@ "name": "Example 7", "actual": 3, "passed": true, - "duration": 0.0012500000000272848 + "duration": 0.0013339999999857355 }, { "input": [ @@ -96,7 +96,7 @@ "name": "Example 8", "actual": 3, "passed": true, - "duration": 0.0012080000000196378 + "duration": 0.0013339999999857355 }, { "input": [ @@ -106,7 +106,7 @@ "name": "Example 9", "actual": 3, "passed": true, - "duration": 0.0017500000000154614 + "duration": 0.0020000000000095497 }, { "input": [ @@ -116,7 +116,7 @@ "name": "Example 10", "actual": 5, "passed": true, - "duration": 0.0019580000000019027 + "duration": 0.002208999999993466 } ], "totalTests": 10, diff --git a/apps/site/src/data/problems/maximum-depth-of-binary-tree.json b/apps/site/src/data/problems/maximum-depth-of-binary-tree.json index 4581db0..afbc1c5 100644 --- a/apps/site/src/data/problems/maximum-depth-of-binary-tree.json +++ b/apps/site/src/data/problems/maximum-depth-of-binary-tree.json @@ -52,7 +52,7 @@ "name": "Example 1", "actual": 3, "passed": true, - "duration": 0.27191699999997354 + "duration": 0.32083399999999074 }, { "input": [ @@ -70,7 +70,7 @@ "name": "Example 2", "actual": 2, "passed": true, - "duration": 0.013958999999999833 + "duration": 0.015375000000005912 } ], "totalTests": 2, @@ -119,7 +119,7 @@ "name": "Example 1", "actual": 3, "passed": true, - "duration": 0.08625000000000682 + "duration": 0.11254100000002154 }, { "input": [ @@ -137,7 +137,7 @@ "name": "Example 2", "actual": 2, "passed": true, - "duration": 0.007040999999958331 + "duration": 0.008916999999996733 } ], "totalTests": 2, @@ -145,7 +145,7 @@ "failedTests": 0 } ], - "notes": "
    \n
    1. \n
    2. Maximum Depth of Binary Tree
    3. \n
    \n
  • \n
  • \n
  • Difficulty: easy
  • \n
  • Tags: tree, depth-first-search, breadth-first-search, binary-tree
  • \n
  • \n
  • Description:
  • \n
  • Given the root of a binary tree, return its maximum depth.
  • \n
  • \n
  • A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
  • \n
  • \n
  • Examples:
  • \n
    1. \n
    2. Input: root = [1,null,2]
    3. \n
    \n
  • \n
  • Output: 2
  • \n
  • \n
  • Constraints:
  • \n
    • \n
    • The number of nodes in the tree is in the range [0, 10^4].
    • \n
    \n
  • \n
    • \n
    • -100 <= Node.val <= 100
    • \n
    \n
  • \n
  • \n
\n", + "notes": "
    \n
    1. \n
    2. Maximum Depth of Binary Tree
    3. \n
    \n
  • \n
  • \n
  • Difficulty: easy
  • \n
  • Tags: tree, depth-first-search, breadth-first-search, binary-tree
  • \n
  • \n
  • Description:
  • \n
  • Given the root of a binary tree, return its maximum depth.
  • \n
  • \n
  • A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
  • \n
  • \n
  • Examples:
  • \n
    1. \n
    2. Input: root = [3,9,20,null,null,15,7]
    3. \n
    \n
  • \n
  • Output: 3
  • \n
    1. \n
    2. Input: root = [1,null,2]
    3. \n
    \n
  • \n
  • Output: 2
  • \n
  • \n
  • Constraints:
  • \n
    • \n
    • The number of nodes in the tree is in the range [0, 10^4].
    • \n
    \n
  • \n
    • \n
    • -100 <= Node.val <= 100
    • \n
    \n
  • \n
  • \n
\n", "totalTests": 4, "passedTests": 4, "failedTests": 0 diff --git a/apps/site/src/data/problems/median-of-two-sorted-arrays.json b/apps/site/src/data/problems/median-of-two-sorted-arrays.json index 0e80091..e3db186 100644 --- a/apps/site/src/data/problems/median-of-two-sorted-arrays.json +++ b/apps/site/src/data/problems/median-of-two-sorted-arrays.json @@ -32,7 +32,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.052957999999989624 + "duration": 0.05991599999998698 }, { "input": [ @@ -49,7 +49,7 @@ "name": "Example 2", "actual": 2.5, "passed": true, - "duration": 0.006250000000022737 + "duration": 0.006624999999985448 }, { "input": [ @@ -66,7 +66,7 @@ "name": "Extended Example 1", "actual": 0, "passed": true, - "duration": 0.002874999999960437 + "duration": 0.00304199999999355 }, { "input": [ @@ -79,7 +79,7 @@ "name": "Extended Example 2", "actual": 1, "passed": true, - "duration": 0.002207999999995991 + "duration": 0.002292000000011285 }, { "input": [ @@ -92,7 +92,7 @@ "name": "Extended Example 3", "actual": 2, "passed": true, - "duration": 0.0020000000000095497 + "duration": 0.0021670000000426626 }, { "input": [ @@ -115,7 +115,7 @@ "name": "Extended Example 4", "actual": 5.5, "passed": true, - "duration": 0.005000000000052296 + "duration": 0.004250000000013188 }, { "input": [ @@ -132,7 +132,7 @@ "name": "Extended Example 5", "actual": 3, "passed": true, - "duration": 0.04820799999998826 + "duration": 0.056417000000010376 } ], "totalTests": 7, @@ -162,7 +162,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.025040999999987434 + "duration": 0.028332999999975073 }, { "input": [ @@ -179,7 +179,7 @@ "name": "Example 2", "actual": 2.5, "passed": true, - "duration": 0.0036249999999995453 + "duration": 0.003999999999962256 }, { "input": [ @@ -196,7 +196,7 @@ "name": "Extended Example 1", "actual": 0, "passed": true, - "duration": 0.0042910000000233595 + "duration": 0.0038749999999936335 }, { "input": [ @@ -209,7 +209,7 @@ "name": "Extended Example 2", "actual": 1, "passed": true, - "duration": 0.0018329999999764368 + "duration": 0.0020419999999603533 }, { "input": [ @@ -222,7 +222,7 @@ "name": "Extended Example 3", "actual": 2, "passed": true, - "duration": 0.002082999999970525 + "duration": 0.002250000000003638 }, { "input": [ @@ -245,7 +245,7 @@ "name": "Extended Example 4", "actual": 5.5, "passed": true, - "duration": 0.007999999999981355 + "duration": 0.009666999999978998 }, { "input": [ @@ -262,7 +262,7 @@ "name": "Extended Example 5", "actual": 3, "passed": true, - "duration": 0.002708000000041011 + "duration": 0.0027919999999994616 } ], "totalTests": 7, diff --git a/apps/site/src/data/problems/sqrt-x.json b/apps/site/src/data/problems/sqrt-x.json index c81d974..8f6d536 100644 --- a/apps/site/src/data/problems/sqrt-x.json +++ b/apps/site/src/data/problems/sqrt-x.json @@ -25,7 +25,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.032083000000000084 + "duration": 0.036875000000009095 }, { "input": [ @@ -35,7 +35,7 @@ "name": "Example 2", "actual": 2, "passed": true, - "duration": 0.0027919999999994616 + "duration": 0.0029590000000325745 }, { "input": [ @@ -45,7 +45,7 @@ "name": "Extended Example 1", "actual": 4, "passed": true, - "duration": 0.001416000000006079 + "duration": 0.0014170000000035543 }, { "input": [ @@ -55,7 +55,7 @@ "name": "Extended Example 2", "actual": 5, "passed": true, - "duration": 0.0010420000000408436 + "duration": 0.0010419999999840002 }, { "input": [ @@ -65,7 +65,7 @@ "name": "Extended Example 3", "actual": 0, "passed": true, - "duration": 0.0578750000000241 + "duration": 0.06158299999998462 }, { "input": [ @@ -75,7 +75,7 @@ "name": "Extended Example 4", "actual": 3, "passed": true, - "duration": 0.0028750000000172804 + "duration": 0.0032090000000266627 }, { "input": [ @@ -85,7 +85,7 @@ "name": "Extended Example 5", "actual": 1, "passed": true, - "duration": 0.001040999999986525 + "duration": 0.0010420000000408436 }, { "input": [ @@ -95,7 +95,7 @@ "name": "Extended Example 6", "actual": 1, "passed": true, - "duration": 0.0008339999999975589 + "duration": 0.0008750000000077307 } ], "totalTests": 8, @@ -119,7 +119,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.01541599999995924 + "duration": 0.035332999999980075 }, { "input": [ @@ -129,7 +129,7 @@ "name": "Example 2", "actual": 2, "passed": true, - "duration": 0.0015000000000213731 + "duration": 0.004750000000001364 }, { "input": [ @@ -139,7 +139,7 @@ "name": "Extended Example 1", "actual": 4, "passed": true, - "duration": 0.002667000000030839 + "duration": 0.004042000000026746 }, { "input": [ @@ -149,7 +149,7 @@ "name": "Extended Example 2", "actual": 5, "passed": true, - "duration": 0.0013749999999959073 + "duration": 0.001458000000013726 }, { "input": [ @@ -159,7 +159,7 @@ "name": "Extended Example 3", "actual": 0, "passed": true, - "duration": 0.0008330000000000837 + "duration": 0.0010000000000331966 }, { "input": [ @@ -179,7 +179,7 @@ "name": "Extended Example 5", "actual": 1, "passed": true, - "duration": 0.0009999999999763531 + "duration": 0.0009589999999661813 }, { "input": [ @@ -189,7 +189,7 @@ "name": "Extended Example 6", "actual": 1, "passed": true, - "duration": 0.0007919999999899119 + "duration": 0.0008330000000000837 } ], "totalTests": 8, diff --git a/apps/site/src/data/problems/two-sum.json b/apps/site/src/data/problems/two-sum.json index 69e19d5..41ca4bd 100644 --- a/apps/site/src/data/problems/two-sum.json +++ b/apps/site/src/data/problems/two-sum.json @@ -37,7 +37,7 @@ 1 ], "passed": true, - "duration": 0.15954200000004448 + "duration": 0.1569170000000213 }, { "input": [ @@ -58,7 +58,7 @@ 2 ], "passed": true, - "duration": 0.08816699999999855 + "duration": 0.08095800000000963 }, { "input": [ @@ -78,7 +78,7 @@ 1 ], "passed": true, - "duration": 0.01245899999997846 + "duration": 0.011292000000025837 }, { "input": [ @@ -106,7 +106,7 @@ 9 ], "passed": true, - "duration": 0.016416999999989912 + "duration": 0.015083000000004176 }, { "input": [ @@ -134,7 +134,7 @@ 9 ], "passed": true, - "duration": 0.01191700000003948 + "duration": 0.012166999999976724 }, { "input": [ @@ -162,7 +162,7 @@ 1 ], "passed": true, - "duration": 0.06370800000001964 + "duration": 0.06099999999997863 } ], "totalTests": 6, @@ -198,7 +198,7 @@ 1 ], "passed": true, - "duration": 0.04870799999997644 + "duration": 0.046875 }, { "input": [ @@ -219,7 +219,7 @@ 2 ], "passed": true, - "duration": 0.004250000000013188 + "duration": 0.005790999999987889 }, { "input": [ @@ -239,7 +239,7 @@ 1 ], "passed": true, - "duration": 0.004916999999977634 + "duration": 0.0038329999999859865 }, { "input": [ @@ -267,7 +267,7 @@ 9 ], "passed": true, - "duration": 0.009833000000014636 + "duration": 0.009166999999990821 }, { "input": [ @@ -295,7 +295,7 @@ 9 ], "passed": true, - "duration": 0.005875000000003183 + "duration": 0.006042000000036296 }, { "input": [ @@ -323,7 +323,7 @@ 1 ], "passed": true, - "duration": 0.00637499999999136 + "duration": 0.007790999999997439 } ], "totalTests": 6, diff --git a/apps/site/src/data/problems/valid-parentheses.json b/apps/site/src/data/problems/valid-parentheses.json index eca29a8..97f940e 100644 --- a/apps/site/src/data/problems/valid-parentheses.json +++ b/apps/site/src/data/problems/valid-parentheses.json @@ -25,7 +25,7 @@ "name": "Example 1", "actual": true, "passed": true, - "duration": 0.06974999999999909 + "duration": 0.06837500000000318 }, { "input": [ @@ -35,7 +35,7 @@ "name": "Example 2", "actual": true, "passed": true, - "duration": 0.005667000000016742 + "duration": 0.005249999999989541 }, { "input": [ @@ -45,7 +45,7 @@ "name": "Example 3", "actual": false, "passed": true, - "duration": 0.006832999999971889 + "duration": 0.01645899999999756 }, { "input": [ @@ -55,7 +55,7 @@ "name": "Example 4", "actual": true, "passed": true, - "duration": 0.004540999999960604 + "duration": 0.0075839999999516294 }, { "input": [ @@ -65,7 +65,7 @@ "name": "Example 5", "actual": false, "passed": true, - "duration": 0.0015829999999823485 + "duration": 0.001791999999966265 } ], "totalTests": 5, diff --git a/packages/src/leetcode-scraper.ts b/packages/src/leetcode-scraper.ts index 700d6db..8f38107 100644 --- a/packages/src/leetcode-scraper.ts +++ b/packages/src/leetcode-scraper.ts @@ -311,8 +311,8 @@ export class LeetCodeScraper { ); const constraints = constraintsMatch ? Array.from(constraintsMatch[1].matchAll(/^\s*[-*]\s+(.+?)\s*$/gm)).map( - (m) => this.normalizeWhitespace(m[1].trim()) - ) + (m) => this.normalizeWhitespace(m[1].trim()) + ) : []; // Extract follow-up questions @@ -321,19 +321,19 @@ export class LeetCodeScraper { ); const followUp = followUpMatch ? followUpMatch[1] - .split('\n') - .map((line) => line.trim()) - .filter((line) => line.length > 0) - .map((line) => { - // Remove extra dashes and clean up markdown formatting - return this.normalizeWhitespace( - line - .replace(/^-\s*/, '') - .replace(/^\*\*\s*/, '') - .replace(/\*\*$/, '') - ); - }) - .filter((line) => line.length > 0) // Filter out empty lines after cleaning + .split('\n') + .map((line) => line.trim()) + .filter((line) => line.length > 0) + .map((line) => { + // Remove extra dashes and clean up markdown formatting + return this.normalizeWhitespace( + line + .replace(/^-\s*/, '') + .replace(/^\*\*\s*/, '') + .replace(/\*\*$/, '') + ); + }) + .filter((line) => line.length > 0) // Filter out empty lines after cleaning : []; // Extract examples @@ -342,17 +342,95 @@ export class LeetCodeScraper { output: string; explanation?: string; }> = []; - const exampleRegex = - /\*{0,2}Example \d+:\*{0,2}\s*\n?\*{0,2}Input:\*{0,2}\s*([^\n]+?)\s*\n?\*{0,2}Output:\*{0,2}\s*([^\n]+?)(?:\s*\n?\*{0,2}Explanation:\*{0,2}\s*([^\n]+?))?(?=\*{0,2}Example|\n\n|$)/gis; - let match; - while ((match = exampleRegex.exec(cleanContent)) !== null) { - examples.push({ - input: this.normalizeWhitespace(match[1].trim()), - output: this.normalizeWhitespace(match[2].trim()), - explanation: match[3] - ? this.normalizeWhitespace(match[3].trim()) - : undefined, - }); + + // Try multiple regex patterns to handle different markdown formats from turndown + // Pattern 1: Standard format with bold markers + // Stop at next Example, Constraints, Follow-up, or end of content + const exampleRegex1 = + /\*{0,2}Example\s+(\d+):\*{0,2}[\s\S]*?\*{0,2}Input:\*{0,2}\s*\n?\s*(.+?)\s*\n\s*\*{0,2}Output:\*{0,2}\s*\n?\s*(.+?)(?:\s*\n\s*\*{0,2}Explanation:\*{0,2}\s*\n?\s*(.+?))?(?=\s*\n\s*\*{0,2}(?:Example\s+\d+|Constraints?|Follow-up):|$)/gis; + + // Pattern 2: Without bold markers (plain text) + // Stop at next Example, Constraints, Follow-up, or end of content + const exampleRegex2 = + /Example\s+(\d+):[\s\S]*?Input:\s*\n?\s*(.+?)\s*\n\s*Output:\s*\n?\s*(.+?)(?:\s*\n\s*Explanation:\s*\n?\s*(.+?))?(?=\s*\n\s*(?:Example\s+\d+|Constraints?|Follow-up):|$)/gis; + + // Pattern 3: More flexible spacing + // Stop at next Example, Constraints, Follow-up, or end of content + const exampleRegex3 = + /\*{0,2}Example\s+(\d+)\*{0,2}[\s\S]*?\*{0,2}Input\*{0,2}[\s\S]*?([^\n]+(?:[\s\S]+?)?)\s*\n\s*\*{0,2}Output\*{0,2}[\s\S]*?([^\n]+(?:[\s\S]+?)?)(?:\s*\n\s*\*{0,2}Explanation\*{0,2}[\s\S]*?([^\n]+(?:[\s\S]+?)?))?(?=\s*\n\s*\*{0,2}(?:Example\s+\d+|Constraints?|Follow-up):|$)/gis; + + const patterns = [exampleRegex1, exampleRegex2, exampleRegex3]; + + for (const pattern of patterns) { + let match; + pattern.lastIndex = 0; // Reset regex + while ((match = pattern.exec(cleanContent)) !== null) { + let input = + match[2]?.trim().replace(/\n\s*/g, ' ').replace(/\s+/g, ' ') || ''; + let output = + match[3]?.trim().replace(/\n\s*/g, ' ').replace(/\s+/g, ' ') || ''; + let explanation = match[4] + ?.trim() + .replace(/\n\s*/g, ' ') + .replace(/\s+/g, ' '); + + // Remove any section headers that might have been captured (Constraints, Follow-up, etc.) + const sectionHeaderRegex = + /\s*\*{0,2}(?:Constraints?|Follow-up):\s*.*$/i; + input = input.replace(sectionHeaderRegex, '').trim(); + output = output.replace(sectionHeaderRegex, '').trim(); + explanation = explanation?.replace(sectionHeaderRegex, '').trim(); + + // Only add if we have valid input and output + if (input && output) { + examples.push({ + input: this.normalizeWhitespace(input), + output: this.normalizeWhitespace(output), + explanation: explanation + ? this.normalizeWhitespace(explanation) + : undefined, + }); + } + } + + // If we found examples, break (don't try other patterns) + if (examples.length > 0) { + break; + } + } + + // Fallback: parse examples directly from HTML if markdown parsing failed + if (examples.length === 0) { + // LeetCode often uses
 tags with Input: and Output:
+      const htmlExampleRegex =
+        /]*>[\s\S]*?]*>Input:\s*<\/strong>\s*([^<]+)[\s\S]*?]*>Output:\s*<\/strong>\s*([^<]+)(?:[\s\S]*?]*>Explanation:\s*<\/strong>\s*([^<]+))?[\s\S]*?<\/pre>/gi;
+      let htmlMatch;
+      while ((htmlMatch = htmlExampleRegex.exec(content)) !== null) {
+        const input =
+          htmlMatch[1]
+            ?.trim()
+            .replace(/ /g, ' ')
+            .replace(/\s+/g, ' ') || '';
+        const output =
+          htmlMatch[2]
+            ?.trim()
+            .replace(/ /g, ' ')
+            .replace(/\s+/g, ' ') || '';
+        const explanation = htmlMatch[3]
+          ?.trim()
+          .replace(/ /g, ' ')
+          .replace(/\s+/g, ' ');
+
+        if (input && output) {
+          examples.push({
+            input: this.normalizeWhitespace(input),
+            output: this.normalizeWhitespace(output),
+            explanation: explanation
+              ? this.normalizeWhitespace(explanation)
+              : undefined,
+          });
+        }
+      }
     }
 
     // Extract main description (everything before constraints, examples, or follow-up)
@@ -462,12 +540,12 @@ export class LeetCodeScraper {
         ? ` *
  * Examples:
 ${content
-  .examples!.map(
-    (example, index) =>
-      ` * ${index + 1}. Input: ${example.input}
+          .examples!.map(
+            (example, index) =>
+              ` * ${index + 1}. Input: ${example.input}
  *    Output: ${example.output}${example.explanation ? `\n *    Explanation: ${example.explanation}` : ''}`
-  )
-  .join('\n')}`
+          )
+          .join('\n')}`
         : ' *';
 
     const constraintsSection =
@@ -492,13 +570,13 @@ ${content.followUp!.map((followUp) => ` * - ${followUp}`).join('\n')}`
  *
  * Description:
 ${cleanedDescription
-  .split('\n')
-  .map((line) => {
-    // Normalize whitespace in each line and remove trailing spaces
-    const normalizedLine = this.normalizeWhitespace(line);
-    return ` * ${normalizedLine}`;
-  })
-  .join('\n')}
+        .split('\n')
+        .map((line) => {
+          // Normalize whitespace in each line and remove trailing spaces
+          const normalizedLine = this.normalizeWhitespace(line);
+          return ` * ${normalizedLine}`;
+        })
+        .join('\n')}
 ${examplesSection}
 ${constraintsSection}
 ${followUpSection}
diff --git a/problems/0104-maximum-depth-of-binary-tree.ts b/problems/0104-maximum-depth-of-binary-tree.ts
index 2bde2e2..6349fc1 100644
--- a/problems/0104-maximum-depth-of-binary-tree.ts
+++ b/problems/0104-maximum-depth-of-binary-tree.ts
@@ -10,7 +10,9 @@
  * A binary tree's **maximum depth** is the number of nodes along the longest path from the root node down to the farthest leaf node.
  *
  * Examples:
- * 1. Input: root = \[1,null,2\]
+ * 1. Input: root = \[3,9,20,null,null,15,7\]
+ *    Output: 3
+ * 2. Input: root = \[1,null,2\]
  *    Output: 2
  *
  * Constraints:
@@ -21,14 +23,6 @@
 import { z } from 'zod';
 import type { TestCase } from '../packages/src/types.js';
 
-// export const TreeNodeSchema: z.ZodType = z.lazy(() =>
-//   z.object({
-//     val: z.number(),
-//     left: z.lazy(() => TreeNodeSchema).nullable(),
-//     right: z.lazy(() => TreeNodeSchema).nullable(),
-//   })
-// );
-
 export class TreeNode {
   val: number;
   left: TreeNode | null;

From d8ae6fcbca476f0c5f943c9e86744419612cbbb6 Mon Sep 17 00:00:00 2001
From: David Chen 
Date: Wed, 5 Nov 2025 14:41:34 -0800
Subject: [PATCH 5/7] added image in the problem description

---
 .../src/data/problems/add-two-numbers.json    |   6 +-
 .../site/src/data/problems/binary-search.json |  10 +-
 ...t-position-of-element-in-sorted-array.json |  12 +-
 .../src/data/problems/find-peak-element.json  |   6 +-
 .../src/data/problems/first-bad-version.json  |  16 +-
 .../guess-number-higher-or-lower.json         |   6 +-
 ...ubstring-without-repeating-characters.json |  18 +--
 .../maximum-depth-of-binary-tree.json         | 145 ++----------------
 .../problems/median-of-two-sorted-arrays.json |  22 +--
 apps/site/src/data/problems/sqrt-x.json       |  32 ++--
 apps/site/src/data/problems/two-sum.json      |  24 +--
 .../src/data/problems/valid-parentheses.json  |  10 +-
 packages/src/build-data.ts                    |  23 ++-
 packages/src/leetcode-scraper.ts              |  30 +++-
 problems/0104-maximum-depth-of-binary-tree.ts | 119 ++------------
 ...104-maximum-depth-of-binary-tree.ts_backup | 140 +++++++++++++++++
 16 files changed, 295 insertions(+), 324 deletions(-)
 create mode 100644 problems/0104-maximum-depth-of-binary-tree.ts_backup

diff --git a/apps/site/src/data/problems/add-two-numbers.json b/apps/site/src/data/problems/add-two-numbers.json
index b5f84e9..b8a5876 100644
--- a/apps/site/src/data/problems/add-two-numbers.json
+++ b/apps/site/src/data/problems/add-two-numbers.json
@@ -72,7 +72,7 @@
             }
           },
           "passed": true,
-          "duration": 0.3231249999999477
+          "duration": 0.33174999999999955
         },
         {
           "input": [
@@ -95,7 +95,7 @@
             "next": null
           },
           "passed": true,
-          "duration": 0.02312499999999318
+          "duration": 0.02333299999997962
         },
         {
           "input": [
@@ -187,7 +187,7 @@
             }
           },
           "passed": true,
-          "duration": 0.020582999999987805
+          "duration": 0.019917000000020835
         }
       ],
       "totalTests": 3,
diff --git a/apps/site/src/data/problems/binary-search.json b/apps/site/src/data/problems/binary-search.json
index 32a20eb..e1da70c 100644
--- a/apps/site/src/data/problems/binary-search.json
+++ b/apps/site/src/data/problems/binary-search.json
@@ -33,7 +33,7 @@
           "name": "Example 1",
           "actual": 4,
           "passed": true,
-          "duration": 0.043083000000024185
+          "duration": 0.041667000000018106
         },
         {
           "input": [
@@ -51,7 +51,7 @@
           "name": "Example 2",
           "actual": -1,
           "passed": true,
-          "duration": 0.003957999999954609
+          "duration": 0.003750000000025011
         },
         {
           "input": [
@@ -69,7 +69,7 @@
           "name": "Example 3",
           "actual": -1,
           "passed": true,
-          "duration": 0.003959000000008928
+          "duration": 0.003458000000023276
         },
         {
           "input": [
@@ -87,7 +87,7 @@
           "name": "Added negative number case",
           "actual": 0,
           "passed": true,
-          "duration": 0.00637499999999136
+          "duration": 0.005667000000016742
         },
         {
           "input": [
@@ -105,7 +105,7 @@
           "name": "Added positive number case",
           "actual": 5,
           "passed": true,
-          "duration": 0.002583000000015545
+          "duration": 0.002417000000036751
         }
       ],
       "totalTests": 5,
diff --git a/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json b/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json
index 67ac6d9..71e766d 100644
--- a/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json
+++ b/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json
@@ -39,7 +39,7 @@
             4
           ],
           "passed": true,
-          "duration": 0.05133299999999963
+          "duration": 0.047416999999995824
         },
         {
           "input": [
@@ -63,7 +63,7 @@
             -1
           ],
           "passed": true,
-          "duration": 0.004083000000036918
+          "duration": 0.005167000000028565
         },
         {
           "input": [
@@ -80,7 +80,7 @@
             -1
           ],
           "passed": true,
-          "duration": 0.0027499999999918145
+          "duration": 0.0030830000000037217
         },
         {
           "input": [
@@ -108,7 +108,7 @@
             0
           ],
           "passed": true,
-          "duration": 0.004000000000019099
+          "duration": 0.00408399999997755
         },
         {
           "input": [
@@ -136,7 +136,7 @@
             9
           ],
           "passed": true,
-          "duration": 0.009375000000034106
+          "duration": 0.00808399999999665
         },
         {
           "input": [
@@ -156,7 +156,7 @@
             1
           ],
           "passed": true,
-          "duration": 0.002417000000036751
+          "duration": 0.0025840000000130203
         }
       ],
       "totalTests": 6,
diff --git a/apps/site/src/data/problems/find-peak-element.json b/apps/site/src/data/problems/find-peak-element.json
index d6621ce..dc884fd 100644
--- a/apps/site/src/data/problems/find-peak-element.json
+++ b/apps/site/src/data/problems/find-peak-element.json
@@ -30,7 +30,7 @@
           "name": "Example 1",
           "actual": 2,
           "passed": true,
-          "duration": 0.04762500000003911
+          "duration": 0.048709000000030755
         },
         {
           "input": [
@@ -48,7 +48,7 @@
           "name": "Example 2",
           "actual": 5,
           "passed": true,
-          "duration": 0.003458000000023276
+          "duration": 0.003290999999990163
         },
         {
           "input": [
@@ -61,7 +61,7 @@
           "name": "Extended example 1",
           "actual": 1,
           "passed": true,
-          "duration": 0.0015839999999798238
+          "duration": 0.001416000000006079
         }
       ],
       "totalTests": 3,
diff --git a/apps/site/src/data/problems/first-bad-version.json b/apps/site/src/data/problems/first-bad-version.json
index 8fc3c1b..fd269b6 100644
--- a/apps/site/src/data/problems/first-bad-version.json
+++ b/apps/site/src/data/problems/first-bad-version.json
@@ -26,7 +26,7 @@
           "name": "Example 1",
           "actual": 1,
           "passed": true,
-          "duration": 0.07362499999999272
+          "duration": 0.06562500000001137
         },
         {
           "input": [
@@ -37,7 +37,7 @@
           "name": "Example 2",
           "actual": 1,
           "passed": true,
-          "duration": 0.005083000000013271
+          "duration": 0.0049579999999878055
         },
         {
           "input": [
@@ -48,7 +48,7 @@
           "name": "Example 3",
           "actual": 2,
           "passed": true,
-          "duration": 0.002625000000023192
+          "duration": 0.0027910000000019863
         },
         {
           "input": [
@@ -59,7 +59,7 @@
           "name": "Example 4",
           "actual": 1,
           "passed": true,
-          "duration": 0.003666000000009717
+          "duration": 0.004249999999956344
         },
         {
           "input": [
@@ -70,7 +70,7 @@
           "name": "Example 5",
           "actual": 4,
           "passed": true,
-          "duration": 0.005207999999981894
+          "duration": 0.0049999999999954525
         },
         {
           "input": [
@@ -81,7 +81,7 @@
           "name": "Example 6",
           "actual": 4,
           "passed": true,
-          "duration": 0.0032500000000368345
+          "duration": 0.0031250000000113687
         },
         {
           "input": [
@@ -92,7 +92,7 @@
           "name": "Example 7",
           "actual": 4,
           "passed": true,
-          "duration": 0.0018330000000332802
+          "duration": 0.0019169999999917309
         },
         {
           "input": [
@@ -103,7 +103,7 @@
           "name": "Example 8",
           "actual": 4,
           "passed": true,
-          "duration": 0.0017920000000231084
+          "duration": 0.0017910000000256332
         }
       ],
       "totalTests": 8,
diff --git a/apps/site/src/data/problems/guess-number-higher-or-lower.json b/apps/site/src/data/problems/guess-number-higher-or-lower.json
index 6a48fd2..219da88 100644
--- a/apps/site/src/data/problems/guess-number-higher-or-lower.json
+++ b/apps/site/src/data/problems/guess-number-higher-or-lower.json
@@ -26,7 +26,7 @@
           "name": "Example 1",
           "actual": 6,
           "passed": true,
-          "duration": 0.07783299999999826
+          "duration": 0.0665419999999699
         },
         {
           "input": [
@@ -37,7 +37,7 @@
           "name": "Example 2",
           "actual": 1,
           "passed": true,
-          "duration": 0.004667000000040389
+          "duration": 0.004625000000032742
         },
         {
           "input": [
@@ -48,7 +48,7 @@
           "name": "Example 3",
           "actual": 1,
           "passed": true,
-          "duration": 0.0025420000000053733
+          "duration": 0.002625000000023192
         }
       ],
       "totalTests": 3,
diff --git a/apps/site/src/data/problems/longest-substring-without-repeating-characters.json b/apps/site/src/data/problems/longest-substring-without-repeating-characters.json
index bcf8636..ab4bccb 100644
--- a/apps/site/src/data/problems/longest-substring-without-repeating-characters.json
+++ b/apps/site/src/data/problems/longest-substring-without-repeating-characters.json
@@ -26,7 +26,7 @@
           "name": "Example 1",
           "actual": 3,
           "passed": true,
-          "duration": 0.0504579999999919
+          "duration": 0.06400000000002137
         },
         {
           "input": [
@@ -36,7 +36,7 @@
           "name": "Example 2",
           "actual": 1,
           "passed": true,
-          "duration": 0.0031670000000190157
+          "duration": 0.0038749999999936335
         },
         {
           "input": [
@@ -46,7 +46,7 @@
           "name": "Example 3",
           "actual": 3,
           "passed": true,
-          "duration": 0.002165999999988344
+          "duration": 0.002166999999985819
         },
         {
           "input": [
@@ -56,7 +56,7 @@
           "name": "Example 4",
           "actual": 1,
           "passed": true,
-          "duration": 0.001167000000009466
+          "duration": 0.0009589999999661813
         },
         {
           "input": [
@@ -66,7 +66,7 @@
           "name": "Example 5",
           "actual": 2,
           "passed": true,
-          "duration": 0.0010420000000408436
+          "duration": 0.0010419999999840002
         },
         {
           "input": [
@@ -76,7 +76,7 @@
           "name": "Example 6",
           "actual": 2,
           "passed": true,
-          "duration": 0.0012910000000374566
+          "duration": 0.0011249999999449756
         },
         {
           "input": [
@@ -96,7 +96,7 @@
           "name": "Example 8",
           "actual": 3,
           "passed": true,
-          "duration": 0.0013339999999857355
+          "duration": 0.0012500000000272848
         },
         {
           "input": [
@@ -106,7 +106,7 @@
           "name": "Example 9",
           "actual": 3,
           "passed": true,
-          "duration": 0.0020000000000095497
+          "duration": 0.0019999999999527063
         },
         {
           "input": [
@@ -116,7 +116,7 @@
           "name": "Example 10",
           "actual": 5,
           "passed": true,
-          "duration": 0.002208999999993466
+          "duration": 0.002124999999978172
         }
       ],
       "totalTests": 10,
diff --git a/apps/site/src/data/problems/maximum-depth-of-binary-tree.json b/apps/site/src/data/problems/maximum-depth-of-binary-tree.json
index afbc1c5..6faea9b 100644
--- a/apps/site/src/data/problems/maximum-depth-of-binary-tree.json
+++ b/apps/site/src/data/problems/maximum-depth-of-binary-tree.json
@@ -11,142 +11,21 @@
   "difficulty": "easy",
   "solutions": [
     {
-      "name": "iterativeSolution",
+      "name": "solution",
       "description": "",
-      "approach": "- Use a stack to traverse the tree iteratively\n - Track the current level and the maximum level\n - Return the maximum level",
-      "timeComplexity": "O(n)",
-      "spaceComplexity": "O(h) where h is the height of the tree",
-      "code": "
const iterativeSolution = (root) => {\n  if (!root) {\n    return 0;\n  }\n  const stack: [TreeNode, number][] = [[root, 1]];\n  let node: TreeNode | null = root;\n  let maxLevel = 0;\n  let currentLevel = 1;\n  while (stack.length > 0 || node !== null) {\n    while (node !== null) {\n      stack.push([node, currentLevel]);\n      node = node.left;\n      currentLevel += 1;\n    }\n\n    const [currentNode, level] = stack.pop() as [TreeNode, number];\n    maxLevel = Math.max(maxLevel, level);\n\n    node = currentNode.right;\n    currentLevel = level + 1;\n  }\n\n  return maxLevel;\n};\n
", - "utilities": [ - { - "name": "TreeNode", - "code": "
class TreeNode {\n  val: number;\n  left: TreeNode | null;\n  right: TreeNode | null;\n  constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {\n    this.val = val ?? 0;\n    this.left = left ?? null;\n    this.right = right ?? null;\n  }\n
" - } - ], - "testResults": [ - { - "input": [ - { - "val": 3, - "left": { - "val": 9, - "left": null, - "right": null - }, - "right": { - "val": 20, - "left": { - "val": 15, - "left": null, - "right": null - }, - "right": { - "val": 7, - "left": null, - "right": null - } - } - } - ], - "expected": 3, - "name": "Example 1", - "actual": 3, - "passed": true, - "duration": 0.32083399999999074 - }, - { - "input": [ - { - "val": 1, - "left": null, - "right": { - "val": 2, - "left": null, - "right": null - } - } - ], - "expected": 2, - "name": "Example 2", - "actual": 2, - "passed": true, - "duration": 0.015375000000005912 - } - ], - "totalTests": 2, - "passedTests": 2, - "failedTests": 0 - }, - { - "name": "recursiveSolution", - "description": "", - "approach": "- Use a recursive function to traverse the tree\n - Return the maximum depth of the left and right subtrees\n - Return the maximum depth of the tree", - "timeComplexity": "O(n)", - "spaceComplexity": "O(h) where h is the height of the tree", - "code": "
const recursiveSolution = (root) => {\n  if (!root) {\n    return 0;\n  }\n  return (\n    1 + Math.max(recursiveSolution(root.left), recursiveSolution(root.right))\n  );\n};\n
", - "utilities": [ - { - "name": "TreeNode", - "code": "
class TreeNode {\n  val: number;\n  left: TreeNode | null;\n  right: TreeNode | null;\n  constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {\n    this.val = val ?? 0;\n    this.left = left ?? null;\n    this.right = right ?? null;\n  }\n
" - } - ], - "testResults": [ - { - "input": [ - { - "val": 3, - "left": { - "val": 9, - "left": null, - "right": null - }, - "right": { - "val": 20, - "left": { - "val": 15, - "left": null, - "right": null - }, - "right": { - "val": 7, - "left": null, - "right": null - } - } - } - ], - "expected": 3, - "name": "Example 1", - "actual": 3, - "passed": true, - "duration": 0.11254100000002154 - }, - { - "input": [ - { - "val": 1, - "left": null, - "right": { - "val": 2, - "left": null, - "right": null - } - } - ], - "expected": 2, - "name": "Example 2", - "actual": 2, - "passed": true, - "duration": 0.008916999999996733 - } - ], - "totalTests": 2, - "passedTests": 2, + "approach": "- Add your approach here", + "timeComplexity": "O()", + "spaceComplexity": "O()", + "code": "
const solution = (root) => {\n  // Your solution here\n  throw new Error('Not implemented');\n};\n
", + "utilities": [], + "testResults": [], + "totalTests": 0, + "passedTests": 0, "failedTests": 0 } ], - "notes": "
    \n
    1. \n
    2. Maximum Depth of Binary Tree
    3. \n
    \n
  • \n
  • \n
  • Difficulty: easy
  • \n
  • Tags: tree, depth-first-search, breadth-first-search, binary-tree
  • \n
  • \n
  • Description:
  • \n
  • Given the root of a binary tree, return its maximum depth.
  • \n
  • \n
  • A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
  • \n
  • \n
  • Examples:
  • \n
    1. \n
    2. Input: root = [3,9,20,null,null,15,7]
    3. \n
    \n
  • \n
  • Output: 3
  • \n
    1. \n
    2. Input: root = [1,null,2]
    3. \n
    \n
  • \n
  • Output: 2
  • \n
  • \n
  • Constraints:
  • \n
    • \n
    • The number of nodes in the tree is in the range [0, 10^4].
    • \n
    \n
  • \n
    • \n
    • -100 <= Node.val <= 100
    • \n
    \n
  • \n
  • \n
\n", - "totalTests": 4, - "passedTests": 4, + "notes": "
    \n
    1. \n
    2. Maximum Depth of Binary Tree
    3. \n
    \n
  • \n
  • \n
  • Difficulty: easy
  • \n
  • Tags: tree, depth-first-search, breadth-first-search, binary-tree
  • \n
  • \n
  • Description:
  • \n
  • Given the root of a binary tree, return its maximum depth.
  • \n
  • \n
  • A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
  • \n
  • \n
  • Examples:
  • \n
    1. \n
    2. Input: root = [3,9,20,null,null,15,7]
    3. \n
    \n
  • \n
  • Output: 3
  • \n
  • \n
  • \"Example
  • \n
    1. \n
    2. Input: root = [1,null,2]
    3. \n
    \n
  • \n
  • Output: 2
  • \n
  • \n
  • Constraints:
  • \n
    • \n
    • The number of nodes in the tree is in the range [0, 10^4].
    • \n
    \n
  • \n
    • \n
    • -100 <= Node.val <= 100
    • \n
    \n
  • \n
  • \n
\n", + "totalTests": 0, + "passedTests": 0, "failedTests": 0 } \ No newline at end of file diff --git a/apps/site/src/data/problems/median-of-two-sorted-arrays.json b/apps/site/src/data/problems/median-of-two-sorted-arrays.json index e3db186..7207201 100644 --- a/apps/site/src/data/problems/median-of-two-sorted-arrays.json +++ b/apps/site/src/data/problems/median-of-two-sorted-arrays.json @@ -32,7 +32,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.05991599999998698 + "duration": 0.07850000000001955 }, { "input": [ @@ -49,7 +49,7 @@ "name": "Example 2", "actual": 2.5, "passed": true, - "duration": 0.006624999999985448 + "duration": 0.006957999999997355 }, { "input": [ @@ -66,7 +66,7 @@ "name": "Extended Example 1", "actual": 0, "passed": true, - "duration": 0.00304199999999355 + "duration": 0.004209000000003016 }, { "input": [ @@ -79,7 +79,7 @@ "name": "Extended Example 2", "actual": 1, "passed": true, - "duration": 0.002292000000011285 + "duration": 0.002333000000021457 }, { "input": [ @@ -132,7 +132,7 @@ "name": "Extended Example 5", "actual": 3, "passed": true, - "duration": 0.056417000000010376 + "duration": 0.06362500000000182 } ], "totalTests": 7, @@ -162,7 +162,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.028332999999975073 + "duration": 0.02941699999996672 }, { "input": [ @@ -179,7 +179,7 @@ "name": "Example 2", "actual": 2.5, "passed": true, - "duration": 0.003999999999962256 + "duration": 0.004042000000026746 }, { "input": [ @@ -196,7 +196,7 @@ "name": "Extended Example 1", "actual": 0, "passed": true, - "duration": 0.0038749999999936335 + "duration": 0.003917000000001281 }, { "input": [ @@ -209,7 +209,7 @@ "name": "Extended Example 2", "actual": 1, "passed": true, - "duration": 0.0020419999999603533 + "duration": 0.0020420000000171967 }, { "input": [ @@ -222,7 +222,7 @@ "name": "Extended Example 3", "actual": 2, "passed": true, - "duration": 0.002250000000003638 + "duration": 0.002999999999985903 }, { "input": [ @@ -245,7 +245,7 @@ "name": "Extended Example 4", "actual": 5.5, "passed": true, - "duration": 0.009666999999978998 + "duration": 0.0116249999999809 }, { "input": [ diff --git a/apps/site/src/data/problems/sqrt-x.json b/apps/site/src/data/problems/sqrt-x.json index 8f6d536..7a38fe4 100644 --- a/apps/site/src/data/problems/sqrt-x.json +++ b/apps/site/src/data/problems/sqrt-x.json @@ -25,7 +25,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.036875000000009095 + "duration": 0.03654199999999719 }, { "input": [ @@ -35,7 +35,7 @@ "name": "Example 2", "actual": 2, "passed": true, - "duration": 0.0029590000000325745 + "duration": 0.003207999999972344 }, { "input": [ @@ -45,7 +45,7 @@ "name": "Extended Example 1", "actual": 4, "passed": true, - "duration": 0.0014170000000035543 + "duration": 0.0014999999999645297 }, { "input": [ @@ -55,7 +55,7 @@ "name": "Extended Example 2", "actual": 5, "passed": true, - "duration": 0.0010419999999840002 + "duration": 0.001125000000001819 }, { "input": [ @@ -65,7 +65,7 @@ "name": "Extended Example 3", "actual": 0, "passed": true, - "duration": 0.06158299999998462 + "duration": 0.060625000000015916 }, { "input": [ @@ -75,7 +75,7 @@ "name": "Extended Example 4", "actual": 3, "passed": true, - "duration": 0.0032090000000266627 + "duration": 0.00304199999999355 }, { "input": [ @@ -85,7 +85,7 @@ "name": "Extended Example 5", "actual": 1, "passed": true, - "duration": 0.0010420000000408436 + "duration": 0.0009579999999687061 }, { "input": [ @@ -95,7 +95,7 @@ "name": "Extended Example 6", "actual": 1, "passed": true, - "duration": 0.0008750000000077307 + "duration": 0.0008330000000000837 } ], "totalTests": 8, @@ -119,7 +119,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.035332999999980075 + "duration": 0.01704100000000608 }, { "input": [ @@ -129,7 +129,7 @@ "name": "Example 2", "actual": 2, "passed": true, - "duration": 0.004750000000001364 + "duration": 0.0015000000000213731 }, { "input": [ @@ -139,7 +139,7 @@ "name": "Extended Example 1", "actual": 4, "passed": true, - "duration": 0.004042000000026746 + "duration": 0.0027919999999994616 }, { "input": [ @@ -149,7 +149,7 @@ "name": "Extended Example 2", "actual": 5, "passed": true, - "duration": 0.001458000000013726 + "duration": 0.0014170000000035543 }, { "input": [ @@ -159,7 +159,7 @@ "name": "Extended Example 3", "actual": 0, "passed": true, - "duration": 0.0010000000000331966 + "duration": 0.0020410000000197215 }, { "input": [ @@ -169,7 +169,7 @@ "name": "Extended Example 4", "actual": 3, "passed": true, - "duration": 0.001125000000001819 + "duration": 0.0010839999999916472 }, { "input": [ @@ -179,7 +179,7 @@ "name": "Extended Example 5", "actual": 1, "passed": true, - "duration": 0.0009589999999661813 + "duration": 0.0009590000000230248 }, { "input": [ @@ -189,7 +189,7 @@ "name": "Extended Example 6", "actual": 1, "passed": true, - "duration": 0.0008330000000000837 + "duration": 0.0007909999999924366 } ], "totalTests": 8, diff --git a/apps/site/src/data/problems/two-sum.json b/apps/site/src/data/problems/two-sum.json index 41ca4bd..2bdd906 100644 --- a/apps/site/src/data/problems/two-sum.json +++ b/apps/site/src/data/problems/two-sum.json @@ -37,7 +37,7 @@ 1 ], "passed": true, - "duration": 0.1569170000000213 + "duration": 0.1588750000000232 }, { "input": [ @@ -58,7 +58,7 @@ 2 ], "passed": true, - "duration": 0.08095800000000963 + "duration": 0.09170899999998028 }, { "input": [ @@ -78,7 +78,7 @@ 1 ], "passed": true, - "duration": 0.011292000000025837 + "duration": 0.016000000000019554 }, { "input": [ @@ -106,7 +106,7 @@ 9 ], "passed": true, - "duration": 0.015083000000004176 + "duration": 0.0160420000000272 }, { "input": [ @@ -134,7 +134,7 @@ 9 ], "passed": true, - "duration": 0.012166999999976724 + "duration": 0.011916999999982636 }, { "input": [ @@ -162,7 +162,7 @@ 1 ], "passed": true, - "duration": 0.06099999999997863 + "duration": 0.06483400000001893 } ], "totalTests": 6, @@ -198,7 +198,7 @@ 1 ], "passed": true, - "duration": 0.046875 + "duration": 0.048292000000003554 }, { "input": [ @@ -219,7 +219,7 @@ 2 ], "passed": true, - "duration": 0.005790999999987889 + "duration": 0.00454199999995808 }, { "input": [ @@ -239,7 +239,7 @@ 1 ], "passed": true, - "duration": 0.0038329999999859865 + "duration": 0.003666000000009717 }, { "input": [ @@ -267,7 +267,7 @@ 9 ], "passed": true, - "duration": 0.009166999999990821 + "duration": 0.10108300000001691 }, { "input": [ @@ -295,7 +295,7 @@ 9 ], "passed": true, - "duration": 0.006042000000036296 + "duration": 0.006041999999979453 }, { "input": [ @@ -323,7 +323,7 @@ 1 ], "passed": true, - "duration": 0.007790999999997439 + "duration": 0.006791000000021086 } ], "totalTests": 6, diff --git a/apps/site/src/data/problems/valid-parentheses.json b/apps/site/src/data/problems/valid-parentheses.json index 97f940e..1f57d87 100644 --- a/apps/site/src/data/problems/valid-parentheses.json +++ b/apps/site/src/data/problems/valid-parentheses.json @@ -25,7 +25,7 @@ "name": "Example 1", "actual": true, "passed": true, - "duration": 0.06837500000000318 + "duration": 0.058207999999979165 }, { "input": [ @@ -35,7 +35,7 @@ "name": "Example 2", "actual": true, "passed": true, - "duration": 0.005249999999989541 + "duration": 0.005084000000010747 }, { "input": [ @@ -45,7 +45,7 @@ "name": "Example 3", "actual": false, "passed": true, - "duration": 0.01645899999999756 + "duration": 0.006542000000024473 }, { "input": [ @@ -55,7 +55,7 @@ "name": "Example 4", "actual": true, "passed": true, - "duration": 0.0075839999999516294 + "duration": 0.0040840000000343935 }, { "input": [ @@ -65,7 +65,7 @@ "name": "Example 5", "actual": false, "passed": true, - "duration": 0.001791999999966265 + "duration": 0.0013749999999959073 } ], "totalTests": 5, diff --git a/packages/src/build-data.ts b/packages/src/build-data.ts index faa8651..03ed007 100644 --- a/packages/src/build-data.ts +++ b/packages/src/build-data.ts @@ -593,17 +593,32 @@ async function extractCodeAndNotes( const rawNotes = tsdocMatch ? tsdocMatch[1].trim() : ''; // Clean up excessive newlines before processing - const cleanedNotes = rawNotes + let cleanedNotes = rawNotes .replace(/^\s*\n/g, '') // Remove leading empty lines .replace(/\n\s*$/g, '') // Remove trailing empty lines .trim(); + // Convert "Image: URL" format to markdown image syntax + // Pattern: * Image: https://example.com/image.png + // Replace with: ![Example image](https://example.com/image.png) + cleanedNotes = cleanedNotes.replace(/\*\s+Image:\s+(\S+)/g, (match, url) => { + // Extract example number if available (from previous lines) + const exampleMatch = cleanedNotes + .substring(0, cleanedNotes.indexOf(match)) + .match(/\*\s+(\d+)\.\s+Input:/); + const exampleNum = exampleMatch ? exampleMatch[1] : ''; + const altText = exampleNum + ? `Example ${exampleNum} image` + : 'Example image'; + return `*\n * ![${altText}](${url})`; + }); + // Process markdown to HTML const notes = cleanedNotes ? await marked.parse(cleanedNotes, { - breaks: true, - gfm: true, - }) + breaks: true, + gfm: true, + }) : ''; // For the new format, we don't need to extract code here since diff --git a/packages/src/leetcode-scraper.ts b/packages/src/leetcode-scraper.ts index 8f38107..8db6e6b 100644 --- a/packages/src/leetcode-scraper.ts +++ b/packages/src/leetcode-scraper.ts @@ -163,7 +163,12 @@ export interface ProblemContent { description: string; constraints?: string[]; followUp?: string[]; - examples?: Array<{ input: string; output: string; explanation?: string }>; + examples?: Array<{ + input: string; + output: string; + explanation?: string; + imageUrl?: string; + }>; } export class LeetCodeScraper { @@ -336,11 +341,26 @@ export class LeetCodeScraper { .filter((line) => line.length > 0) // Filter out empty lines after cleaning : []; + // First, extract image URLs from HTML content before markdown conversion + // Images are typically in tags within example sections + const imageUrlRegex = /]+src=["']([^"']+)["'][^>]*>/gi; + const imageUrls: string[] = []; + let imageMatch; + while ((imageMatch = imageUrlRegex.exec(content)) !== null) { + const imageUrl = imageMatch[1]; + // Only include images that look like LeetCode example images + // Usually they're hosted on LeetCode CDN or are relative paths + if (imageUrl && !imageUrl.startsWith('data:')) { + imageUrls.push(imageUrl); + } + } + // Extract examples const examples: Array<{ input: string; output: string; explanation?: string; + imageUrl?: string; }> = []; // Try multiple regex patterns to handle different markdown formats from turndown @@ -383,12 +403,15 @@ export class LeetCodeScraper { // Only add if we have valid input and output if (input && output) { + // Try to match image URL to this example (by index) + const imageUrl = imageUrls[examples.length] || undefined; examples.push({ input: this.normalizeWhitespace(input), output: this.normalizeWhitespace(output), explanation: explanation ? this.normalizeWhitespace(explanation) : undefined, + imageUrl: imageUrl, }); } } @@ -422,12 +445,15 @@ export class LeetCodeScraper { .replace(/\s+/g, ' '); if (input && output) { + // Try to match image URL to this example (by index) + const imageUrl = imageUrls[examples.length] || undefined; examples.push({ input: this.normalizeWhitespace(input), output: this.normalizeWhitespace(output), explanation: explanation ? this.normalizeWhitespace(explanation) : undefined, + imageUrl: imageUrl, }); } } @@ -543,7 +569,7 @@ ${content .examples!.map( (example, index) => ` * ${index + 1}. Input: ${example.input} - * Output: ${example.output}${example.explanation ? `\n * Explanation: ${example.explanation}` : ''}` + * Output: ${example.output}${example.explanation ? `\n * Explanation: ${example.explanation}` : ''}${example.imageUrl ? `\n * Image: ${example.imageUrl}` : ''}` ) .join('\n')}` : ' *'; diff --git a/problems/0104-maximum-depth-of-binary-tree.ts b/problems/0104-maximum-depth-of-binary-tree.ts index 6349fc1..3c0dbf9 100644 --- a/problems/0104-maximum-depth-of-binary-tree.ts +++ b/problems/0104-maximum-depth-of-binary-tree.ts @@ -6,12 +6,13 @@ * * Description: * Given the `root` of a binary tree, return _its maximum depth_. - * + * * A binary tree's **maximum depth** is the number of nodes along the longest path from the root node down to the farthest leaf node. * * Examples: * 1. Input: root = \[3,9,20,null,null,15,7\] * Output: 3 + * Image: https://assets.leetcode.com/uploads/2020/11/26/tmp-tree.jpg * 2. Input: root = \[1,null,2\] * Output: 2 * @@ -23,118 +24,28 @@ import { z } from 'zod'; import type { TestCase } from '../packages/src/types.js'; -export class TreeNode { - val: number; - left: TreeNode | null; - right: TreeNode | null; - constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { - this.val = val ?? 0; - this.left = left ?? null; - this.right = right ?? null; - } -} - -export const TreeNodeSchema = z - .instanceof(TreeNode) - .check( - z.property('val', z.number()), - z.property('left', z.lazy(() => TreeNodeSchema).nullable()), - z.property('right', z.lazy(() => TreeNodeSchema).nullable()) - ); - export const SolutionSchema = z.function({ - input: [TreeNodeSchema.nullable()], - output: z.number(), + input: [z.any()], + output: z.number() }); export type Solution = z.infer; -const arrayToTreeNode = (array: (number | null)[]): TreeNode => { - if (array.length === 0) { - throw new Error('Array is empty'); - } - const root = new TreeNode(array[0]!); - const queue: (TreeNode | null)[] = [root]; - - for (let index = 1; index < array.length + 1; index += 2) { - const node = queue.shift(); - if (node) { - node.left = array[index] ? new TreeNode(array[index]!) : null; - queue.push(node.left); - if (index + 1 < array.length) { - node.right = array[index + 1] ? new TreeNode(array[index + 1]!) : null; - queue.push(node.right); - } - } - } - return root; -}; - export const cases: TestCase[] = [ - { - input: [arrayToTreeNode([3, 9, 20, null, null, 15, 7])], - expected: 3, - name: 'Example 1', - }, - { - input: [arrayToTreeNode([1, null, 2])], - expected: 2, - name: 'Example 2', - }, + // Add your test cases here + // { input: [/* your input values */], expected: /* expected output */, name: 'Example 1' }, ]; /** - * Iterative Solution - * @utilities: TreeNode - * Approach: - * - Use a stack to traverse the tree iteratively - * - Track the current level and the maximum level - * - Return the maximum level - * Time Complexity: O(n) - * Space Complexity: O(h) where h is the height of the tree - */ -export const iterativeSolution = SolutionSchema.implement((root) => { - if (!root) { - return 0; - } - const stack: [TreeNode, number][] = [[root, 1]]; - let node: TreeNode | null = root; - let maxLevel = 0; - let currentLevel = 1; - while (stack.length > 0 || node !== null) { - while (node !== null) { - stack.push([node, currentLevel]); - node = node.left; - currentLevel += 1; - } - - const [currentNode, level] = stack.pop() as [TreeNode, number]; - maxLevel = Math.max(maxLevel, level); - - node = currentNode.right; - currentLevel = level + 1; - } - - return maxLevel; -}); - -/** - * Recursive Solution - * @utilities: TreeNode - * Approach: - * - Use a recursive function to traverse the tree - * - Return the maximum depth of the left and right subtrees - * - Return the maximum depth of the tree - * Time Complexity: O(n) - * Space Complexity: O(h) where h is the height of the tree + * Solution + * Approach: + * - Add your approach here + * Time Complexity: O() + * Space Complexity: O() */ -export const recursiveSolution = SolutionSchema.implement((root) => { - if (!root) { - return 0; - } - return ( - 1 + Math.max(recursiveSolution(root.left), recursiveSolution(root.right)) - ); +export const solution = SolutionSchema.implement((root) => { + // Your solution here + throw new Error('Not implemented'); }); -export const solutions = [iterativeSolution, recursiveSolution]; +export const solutions = [solution]; diff --git a/problems/0104-maximum-depth-of-binary-tree.ts_backup b/problems/0104-maximum-depth-of-binary-tree.ts_backup new file mode 100644 index 0000000..6349fc1 --- /dev/null +++ b/problems/0104-maximum-depth-of-binary-tree.ts_backup @@ -0,0 +1,140 @@ +/** + * 0104. Maximum Depth of Binary Tree + * + * Difficulty: easy + * Tags: tree, depth-first-search, breadth-first-search, binary-tree + * + * Description: + * Given the `root` of a binary tree, return _its maximum depth_. + * + * A binary tree's **maximum depth** is the number of nodes along the longest path from the root node down to the farthest leaf node. + * + * Examples: + * 1. Input: root = \[3,9,20,null,null,15,7\] + * Output: 3 + * 2. Input: root = \[1,null,2\] + * Output: 2 + * + * Constraints: + * - The number of nodes in the tree is in the range `[0, 10^4]`. + * - `-100 <= Node.val <= 100` + * + */ +import { z } from 'zod'; +import type { TestCase } from '../packages/src/types.js'; + +export class TreeNode { + val: number; + left: TreeNode | null; + right: TreeNode | null; + constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + this.val = val ?? 0; + this.left = left ?? null; + this.right = right ?? null; + } +} + +export const TreeNodeSchema = z + .instanceof(TreeNode) + .check( + z.property('val', z.number()), + z.property('left', z.lazy(() => TreeNodeSchema).nullable()), + z.property('right', z.lazy(() => TreeNodeSchema).nullable()) + ); + +export const SolutionSchema = z.function({ + input: [TreeNodeSchema.nullable()], + output: z.number(), +}); + +export type Solution = z.infer; + +const arrayToTreeNode = (array: (number | null)[]): TreeNode => { + if (array.length === 0) { + throw new Error('Array is empty'); + } + const root = new TreeNode(array[0]!); + const queue: (TreeNode | null)[] = [root]; + + for (let index = 1; index < array.length + 1; index += 2) { + const node = queue.shift(); + if (node) { + node.left = array[index] ? new TreeNode(array[index]!) : null; + queue.push(node.left); + if (index + 1 < array.length) { + node.right = array[index + 1] ? new TreeNode(array[index + 1]!) : null; + queue.push(node.right); + } + } + } + return root; +}; + +export const cases: TestCase[] = [ + { + input: [arrayToTreeNode([3, 9, 20, null, null, 15, 7])], + expected: 3, + name: 'Example 1', + }, + { + input: [arrayToTreeNode([1, null, 2])], + expected: 2, + name: 'Example 2', + }, +]; + +/** + * Iterative Solution + * @utilities: TreeNode + * Approach: + * - Use a stack to traverse the tree iteratively + * - Track the current level and the maximum level + * - Return the maximum level + * Time Complexity: O(n) + * Space Complexity: O(h) where h is the height of the tree + */ +export const iterativeSolution = SolutionSchema.implement((root) => { + if (!root) { + return 0; + } + const stack: [TreeNode, number][] = [[root, 1]]; + let node: TreeNode | null = root; + let maxLevel = 0; + let currentLevel = 1; + while (stack.length > 0 || node !== null) { + while (node !== null) { + stack.push([node, currentLevel]); + node = node.left; + currentLevel += 1; + } + + const [currentNode, level] = stack.pop() as [TreeNode, number]; + maxLevel = Math.max(maxLevel, level); + + node = currentNode.right; + currentLevel = level + 1; + } + + return maxLevel; +}); + +/** + * Recursive Solution + * @utilities: TreeNode + * Approach: + * - Use a recursive function to traverse the tree + * - Return the maximum depth of the left and right subtrees + * - Return the maximum depth of the tree + * Time Complexity: O(n) + * Space Complexity: O(h) where h is the height of the tree + */ +export const recursiveSolution = SolutionSchema.implement((root) => { + if (!root) { + return 0; + } + return ( + 1 + Math.max(recursiveSolution(root.left), recursiveSolution(root.right)) + ); +}); + +export const solutions = [iterativeSolution, recursiveSolution]; From f5811030b3fd8671b41d7ce54e3279fd7b3afba8 Mon Sep 17 00:00:00 2001 From: David Chen Date: Wed, 5 Nov 2025 14:54:00 -0800 Subject: [PATCH 6/7] fixed lint --- packages/src/leetcode-scraper.ts | 80 +++++++++++--------------------- 1 file changed, 27 insertions(+), 53 deletions(-) diff --git a/packages/src/leetcode-scraper.ts b/packages/src/leetcode-scraper.ts index 8db6e6b..30fd17e 100644 --- a/packages/src/leetcode-scraper.ts +++ b/packages/src/leetcode-scraper.ts @@ -316,8 +316,8 @@ export class LeetCodeScraper { ); const constraints = constraintsMatch ? Array.from(constraintsMatch[1].matchAll(/^\s*[-*]\s+(.+?)\s*$/gm)).map( - (m) => this.normalizeWhitespace(m[1].trim()) - ) + (m) => this.normalizeWhitespace(m[1].trim()) + ) : []; // Extract follow-up questions @@ -326,19 +326,19 @@ export class LeetCodeScraper { ); const followUp = followUpMatch ? followUpMatch[1] - .split('\n') - .map((line) => line.trim()) - .filter((line) => line.length > 0) - .map((line) => { - // Remove extra dashes and clean up markdown formatting - return this.normalizeWhitespace( - line - .replace(/^-\s*/, '') - .replace(/^\*\*\s*/, '') - .replace(/\*\*$/, '') - ); - }) - .filter((line) => line.length > 0) // Filter out empty lines after cleaning + .split('\n') + .map((line) => line.trim()) + .filter((line) => line.length > 0) + .map((line) => { + // Remove extra dashes and clean up markdown formatting + return this.normalizeWhitespace( + line + .replace(/^-\s*/, '') + .replace(/^\*\*\s*/, '') + .replace(/\*\*$/, '') + ); + }) + .filter((line) => line.length > 0) // Filter out empty lines after cleaning : []; // First, extract image URLs from HTML content before markdown conversion @@ -566,12 +566,12 @@ export class LeetCodeScraper { ? ` * * Examples: ${content - .examples!.map( - (example, index) => - ` * ${index + 1}. Input: ${example.input} + .examples!.map( + (example, index) => + ` * ${index + 1}. Input: ${example.input} * Output: ${example.output}${example.explanation ? `\n * Explanation: ${example.explanation}` : ''}${example.imageUrl ? `\n * Image: ${example.imageUrl}` : ''}` - ) - .join('\n')}` + ) + .join('\n')}` : ' *'; const constraintsSection = @@ -596,13 +596,13 @@ ${content.followUp!.map((followUp) => ` * - ${followUp}`).join('\n')}` * * Description: ${cleanedDescription - .split('\n') - .map((line) => { - // Normalize whitespace in each line and remove trailing spaces - const normalizedLine = this.normalizeWhitespace(line); - return ` * ${normalizedLine}`; - }) - .join('\n')} + .split('\n') + .map((line) => { + // Normalize whitespace in each line and remove trailing spaces + const normalizedLine = this.normalizeWhitespace(line); + return ` * ${normalizedLine}`; + }) + .join('\n')} ${examplesSection} ${constraintsSection} ${followUpSection} @@ -637,32 +637,6 @@ export const solutions = [solution]; `; } - private inferOutputType( - examples: Array<{ output: string }> | undefined - ): string { - if (examples?.length === 0) return 'any'; - - try { - const firstOutput = JSON.parse(examples![0].output); - - if (Array.isArray(firstOutput)) { - if (firstOutput.length === 0) return 'any[]'; - if (typeof firstOutput[0] === 'number') return 'number[]'; - if (typeof firstOutput[0] === 'string') return 'string[]'; - if (typeof firstOutput[0] === 'boolean') return 'boolean[]'; - return 'any[]'; - } - - if (typeof firstOutput === 'number') return 'number'; - if (typeof firstOutput === 'string') return 'string'; - if (typeof firstOutput === 'boolean') return 'boolean'; - - return 'any'; - } catch { - return 'any'; - } - } - private generateZodInputTypes(metaData: string): string { try { const parsed = JSON.parse(metaData); From 191cd16a01d668c353c96fdfbf5bdbcfcbe31264 Mon Sep 17 00:00:00 2001 From: David Chen Date: Wed, 5 Nov 2025 14:55:55 -0800 Subject: [PATCH 7/7] fixed lint --- .../src/data/problems/add-two-numbers.json | 6 +- .../site/src/data/problems/binary-search.json | 10 +- ...t-position-of-element-in-sorted-array.json | 12 +- .../src/data/problems/find-peak-element.json | 6 +- .../src/data/problems/first-bad-version.json | 16 +- .../guess-number-higher-or-lower.json | 6 +- ...ubstring-without-repeating-characters.json | 18 +-- .../maximum-depth-of-binary-tree.json | 143 ++++++++++++++++-- .../problems/median-of-two-sorted-arrays.json | 28 ++-- apps/site/src/data/problems/sqrt-x.json | 24 +-- apps/site/src/data/problems/two-sum.json | 24 +-- .../src/data/problems/valid-parentheses.json | 10 +- problems/0104-maximum-depth-of-binary-tree.ts | 118 +++++++++++++-- ...104-maximum-depth-of-binary-tree.ts_backup | 140 ----------------- 14 files changed, 316 insertions(+), 245 deletions(-) delete mode 100644 problems/0104-maximum-depth-of-binary-tree.ts_backup diff --git a/apps/site/src/data/problems/add-two-numbers.json b/apps/site/src/data/problems/add-two-numbers.json index b8a5876..4759c8f 100644 --- a/apps/site/src/data/problems/add-two-numbers.json +++ b/apps/site/src/data/problems/add-two-numbers.json @@ -72,7 +72,7 @@ } }, "passed": true, - "duration": 0.33174999999999955 + "duration": 0.3307909999999765 }, { "input": [ @@ -95,7 +95,7 @@ "next": null }, "passed": true, - "duration": 0.02333299999997962 + "duration": 0.02174999999999727 }, { "input": [ @@ -187,7 +187,7 @@ } }, "passed": true, - "duration": 0.019917000000020835 + "duration": 0.02029099999998607 } ], "totalTests": 3, diff --git a/apps/site/src/data/problems/binary-search.json b/apps/site/src/data/problems/binary-search.json index e1da70c..db561a8 100644 --- a/apps/site/src/data/problems/binary-search.json +++ b/apps/site/src/data/problems/binary-search.json @@ -33,7 +33,7 @@ "name": "Example 1", "actual": 4, "passed": true, - "duration": 0.041667000000018106 + "duration": 0.0362920000000031 }, { "input": [ @@ -51,7 +51,7 @@ "name": "Example 2", "actual": -1, "passed": true, - "duration": 0.003750000000025011 + "duration": 0.0036670000000071923 }, { "input": [ @@ -69,7 +69,7 @@ "name": "Example 3", "actual": -1, "passed": true, - "duration": 0.003458000000023276 + "duration": 0.003708000000017364 }, { "input": [ @@ -87,7 +87,7 @@ "name": "Added negative number case", "actual": 0, "passed": true, - "duration": 0.005667000000016742 + "duration": 0.0054580000000328255 }, { "input": [ @@ -105,7 +105,7 @@ "name": "Added positive number case", "actual": 5, "passed": true, - "duration": 0.002417000000036751 + "duration": 0.0024999999999977263 } ], "totalTests": 5, diff --git a/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json b/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json index 71e766d..2b584f7 100644 --- a/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json +++ b/apps/site/src/data/problems/find-first-and-last-position-of-element-in-sorted-array.json @@ -39,7 +39,7 @@ 4 ], "passed": true, - "duration": 0.047416999999995824 + "duration": 0.053124999999965894 }, { "input": [ @@ -63,7 +63,7 @@ -1 ], "passed": true, - "duration": 0.005167000000028565 + "duration": 0.003917000000001281 }, { "input": [ @@ -80,7 +80,7 @@ -1 ], "passed": true, - "duration": 0.0030830000000037217 + "duration": 0.004958999999985281 }, { "input": [ @@ -108,7 +108,7 @@ 0 ], "passed": true, - "duration": 0.00408399999997755 + "duration": 0.004041999999969903 }, { "input": [ @@ -136,7 +136,7 @@ 9 ], "passed": true, - "duration": 0.00808399999999665 + "duration": 0.008874999999989086 }, { "input": [ @@ -156,7 +156,7 @@ 1 ], "passed": true, - "duration": 0.0025840000000130203 + "duration": 0.002417000000036751 } ], "totalTests": 6, diff --git a/apps/site/src/data/problems/find-peak-element.json b/apps/site/src/data/problems/find-peak-element.json index dc884fd..4900cdb 100644 --- a/apps/site/src/data/problems/find-peak-element.json +++ b/apps/site/src/data/problems/find-peak-element.json @@ -30,7 +30,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.048709000000030755 + "duration": 0.04250000000001819 }, { "input": [ @@ -48,7 +48,7 @@ "name": "Example 2", "actual": 5, "passed": true, - "duration": 0.003290999999990163 + "duration": 0.004624999999975898 }, { "input": [ @@ -61,7 +61,7 @@ "name": "Extended example 1", "actual": 1, "passed": true, - "duration": 0.001416000000006079 + "duration": 0.0016249999999899956 } ], "totalTests": 3, diff --git a/apps/site/src/data/problems/first-bad-version.json b/apps/site/src/data/problems/first-bad-version.json index fd269b6..a373826 100644 --- a/apps/site/src/data/problems/first-bad-version.json +++ b/apps/site/src/data/problems/first-bad-version.json @@ -26,7 +26,7 @@ "name": "Example 1", "actual": 1, "passed": true, - "duration": 0.06562500000001137 + "duration": 0.06541600000002745 }, { "input": [ @@ -37,7 +37,7 @@ "name": "Example 2", "actual": 1, "passed": true, - "duration": 0.0049579999999878055 + "duration": 0.004750000000001364 }, { "input": [ @@ -48,7 +48,7 @@ "name": "Example 3", "actual": 2, "passed": true, - "duration": 0.0027910000000019863 + "duration": 0.002708000000041011 }, { "input": [ @@ -59,7 +59,7 @@ "name": "Example 4", "actual": 1, "passed": true, - "duration": 0.004249999999956344 + "duration": 0.0036670000000071923 }, { "input": [ @@ -70,7 +70,7 @@ "name": "Example 5", "actual": 4, "passed": true, - "duration": 0.0049999999999954525 + "duration": 0.007000000000005002 }, { "input": [ @@ -81,7 +81,7 @@ "name": "Example 6", "actual": 4, "passed": true, - "duration": 0.0031250000000113687 + "duration": 0.002999999999985903 }, { "input": [ @@ -92,7 +92,7 @@ "name": "Example 7", "actual": 4, "passed": true, - "duration": 0.0019169999999917309 + "duration": 0.0018330000000332802 }, { "input": [ @@ -103,7 +103,7 @@ "name": "Example 8", "actual": 4, "passed": true, - "duration": 0.0017910000000256332 + "duration": 0.0017080000000078144 } ], "totalTests": 8, diff --git a/apps/site/src/data/problems/guess-number-higher-or-lower.json b/apps/site/src/data/problems/guess-number-higher-or-lower.json index 219da88..608c0c1 100644 --- a/apps/site/src/data/problems/guess-number-higher-or-lower.json +++ b/apps/site/src/data/problems/guess-number-higher-or-lower.json @@ -26,7 +26,7 @@ "name": "Example 1", "actual": 6, "passed": true, - "duration": 0.0665419999999699 + "duration": 0.08329099999997425 }, { "input": [ @@ -37,7 +37,7 @@ "name": "Example 2", "actual": 1, "passed": true, - "duration": 0.004625000000032742 + "duration": 0.0044999999999504325 }, { "input": [ @@ -48,7 +48,7 @@ "name": "Example 3", "actual": 1, "passed": true, - "duration": 0.002625000000023192 + "duration": 0.0024579999999900792 } ], "totalTests": 3, diff --git a/apps/site/src/data/problems/longest-substring-without-repeating-characters.json b/apps/site/src/data/problems/longest-substring-without-repeating-characters.json index ab4bccb..2c60c2e 100644 --- a/apps/site/src/data/problems/longest-substring-without-repeating-characters.json +++ b/apps/site/src/data/problems/longest-substring-without-repeating-characters.json @@ -26,7 +26,7 @@ "name": "Example 1", "actual": 3, "passed": true, - "duration": 0.06400000000002137 + "duration": 0.050957999999980075 }, { "input": [ @@ -36,7 +36,7 @@ "name": "Example 2", "actual": 1, "passed": true, - "duration": 0.0038749999999936335 + "duration": 0.0030409999999960746 }, { "input": [ @@ -46,7 +46,7 @@ "name": "Example 3", "actual": 3, "passed": true, - "duration": 0.002166999999985819 + "duration": 0.0020000000000095497 }, { "input": [ @@ -56,7 +56,7 @@ "name": "Example 4", "actual": 1, "passed": true, - "duration": 0.0009589999999661813 + "duration": 0.001167000000009466 }, { "input": [ @@ -66,7 +66,7 @@ "name": "Example 5", "actual": 2, "passed": true, - "duration": 0.0010419999999840002 + "duration": 0.0009590000000230248 }, { "input": [ @@ -76,7 +76,7 @@ "name": "Example 6", "actual": 2, "passed": true, - "duration": 0.0011249999999449756 + "duration": 0.001167000000009466 }, { "input": [ @@ -86,7 +86,7 @@ "name": "Example 7", "actual": 3, "passed": true, - "duration": 0.0013339999999857355 + "duration": 0.0012920000000349319 }, { "input": [ @@ -106,7 +106,7 @@ "name": "Example 9", "actual": 3, "passed": true, - "duration": 0.0019999999999527063 + "duration": 0.0018330000000332802 }, { "input": [ @@ -116,7 +116,7 @@ "name": "Example 10", "actual": 5, "passed": true, - "duration": 0.002124999999978172 + "duration": 0.0020420000000171967 } ], "totalTests": 10, diff --git a/apps/site/src/data/problems/maximum-depth-of-binary-tree.json b/apps/site/src/data/problems/maximum-depth-of-binary-tree.json index 6faea9b..ee0dfeb 100644 --- a/apps/site/src/data/problems/maximum-depth-of-binary-tree.json +++ b/apps/site/src/data/problems/maximum-depth-of-binary-tree.json @@ -11,21 +11,142 @@ "difficulty": "easy", "solutions": [ { - "name": "solution", + "name": "iterativeSolution", "description": "", - "approach": "- Add your approach here", - "timeComplexity": "O()", - "spaceComplexity": "O()", - "code": "
const solution = (root) => {\n  // Your solution here\n  throw new Error('Not implemented');\n};\n
", - "utilities": [], - "testResults": [], - "totalTests": 0, - "passedTests": 0, + "approach": "- Use a stack to traverse the tree iteratively\n - Track the current level and the maximum level\n - Return the maximum level", + "timeComplexity": "O(n)", + "spaceComplexity": "O(h) where h is the height of the tree", + "code": "
const iterativeSolution = (root) => {\n  if (!root) {\n    return 0;\n  }\n  const stack: [TreeNode, number][] = [[root, 1]];\n  let node: TreeNode | null = root;\n  let maxLevel = 0;\n  let currentLevel = 1;\n  while (stack.length > 0 || node !== null) {\n    while (node !== null) {\n      stack.push([node, currentLevel]);\n      node = node.left;\n      currentLevel += 1;\n    }\n\n    const [currentNode, level] = stack.pop() as [TreeNode, number];\n    maxLevel = Math.max(maxLevel, level);\n\n    node = currentNode.right;\n    currentLevel = level + 1;\n  }\n\n  return maxLevel;\n};\n
", + "utilities": [ + { + "name": "TreeNode", + "code": "
class TreeNode {\n  val: number;\n  left: TreeNode | null;\n  right: TreeNode | null;\n  constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {\n    this.val = val ?? 0;\n    this.left = left ?? null;\n    this.right = right ?? null;\n  }\n
" + } + ], + "testResults": [ + { + "input": [ + { + "val": 3, + "left": { + "val": 9, + "left": null, + "right": null + }, + "right": { + "val": 20, + "left": { + "val": 15, + "left": null, + "right": null + }, + "right": { + "val": 7, + "left": null, + "right": null + } + } + } + ], + "expected": 3, + "name": "Example 1", + "actual": 3, + "passed": true, + "duration": 0.26770800000002737 + }, + { + "input": [ + { + "val": 1, + "left": null, + "right": { + "val": 2, + "left": null, + "right": null + } + } + ], + "expected": 2, + "name": "Example 2", + "actual": 2, + "passed": true, + "duration": 0.014667000000031294 + } + ], + "totalTests": 2, + "passedTests": 2, + "failedTests": 0 + }, + { + "name": "recursiveSolution", + "description": "", + "approach": "- Use a recursive function to traverse the tree\n - Return the maximum depth of the left and right subtrees\n - Return the maximum depth of the tree", + "timeComplexity": "O(n)", + "spaceComplexity": "O(h) where h is the height of the tree", + "code": "
const recursiveSolution = (root) => {\n  if (!root) {\n    return 0;\n  }\n  return (\n    1 + Math.max(recursiveSolution(root.left), recursiveSolution(root.right))\n  );\n};\n
", + "utilities": [ + { + "name": "TreeNode", + "code": "
class TreeNode {\n  val: number;\n  left: TreeNode | null;\n  right: TreeNode | null;\n  constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {\n    this.val = val ?? 0;\n    this.left = left ?? null;\n    this.right = right ?? null;\n  }\n
" + } + ], + "testResults": [ + { + "input": [ + { + "val": 3, + "left": { + "val": 9, + "left": null, + "right": null + }, + "right": { + "val": 20, + "left": { + "val": 15, + "left": null, + "right": null + }, + "right": { + "val": 7, + "left": null, + "right": null + } + } + } + ], + "expected": 3, + "name": "Example 1", + "actual": 3, + "passed": true, + "duration": 0.09166699999997263 + }, + { + "input": [ + { + "val": 1, + "left": null, + "right": { + "val": 2, + "left": null, + "right": null + } + } + ], + "expected": 2, + "name": "Example 2", + "actual": 2, + "passed": true, + "duration": 0.0072499999999990905 + } + ], + "totalTests": 2, + "passedTests": 2, "failedTests": 0 } ], "notes": "
    \n
    1. \n
    2. Maximum Depth of Binary Tree
    3. \n
    \n
  • \n
  • \n
  • Difficulty: easy
  • \n
  • Tags: tree, depth-first-search, breadth-first-search, binary-tree
  • \n
  • \n
  • Description:
  • \n
  • Given the root of a binary tree, return its maximum depth.
  • \n
  • \n
  • A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
  • \n
  • \n
  • Examples:
  • \n
    1. \n
    2. Input: root = [3,9,20,null,null,15,7]
    3. \n
    \n
  • \n
  • Output: 3
  • \n
  • \n
  • \"Example
  • \n
    1. \n
    2. Input: root = [1,null,2]
    3. \n
    \n
  • \n
  • Output: 2
  • \n
  • \n
  • Constraints:
  • \n
    • \n
    • The number of nodes in the tree is in the range [0, 10^4].
    • \n
    \n
  • \n
    • \n
    • -100 <= Node.val <= 100
    • \n
    \n
  • \n
  • \n
\n", - "totalTests": 0, - "passedTests": 0, + "totalTests": 4, + "passedTests": 4, "failedTests": 0 } \ No newline at end of file diff --git a/apps/site/src/data/problems/median-of-two-sorted-arrays.json b/apps/site/src/data/problems/median-of-two-sorted-arrays.json index 7207201..429eee7 100644 --- a/apps/site/src/data/problems/median-of-two-sorted-arrays.json +++ b/apps/site/src/data/problems/median-of-two-sorted-arrays.json @@ -32,7 +32,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.07850000000001955 + "duration": 0.061790999999971064 }, { "input": [ @@ -49,7 +49,7 @@ "name": "Example 2", "actual": 2.5, "passed": true, - "duration": 0.006957999999997355 + "duration": 0.006832999999971889 }, { "input": [ @@ -66,7 +66,7 @@ "name": "Extended Example 1", "actual": 0, "passed": true, - "duration": 0.004209000000003016 + "duration": 0.0029170000000249274 }, { "input": [ @@ -79,7 +79,7 @@ "name": "Extended Example 2", "actual": 1, "passed": true, - "duration": 0.002333000000021457 + "duration": 0.002292000000011285 }, { "input": [ @@ -92,7 +92,7 @@ "name": "Extended Example 3", "actual": 2, "passed": true, - "duration": 0.0021670000000426626 + "duration": 0.003459000000020751 }, { "input": [ @@ -115,7 +115,7 @@ "name": "Extended Example 4", "actual": 5.5, "passed": true, - "duration": 0.004250000000013188 + "duration": 0.0042910000000233595 }, { "input": [ @@ -132,7 +132,7 @@ "name": "Extended Example 5", "actual": 3, "passed": true, - "duration": 0.06362500000000182 + "duration": 0.05816700000002584 } ], "totalTests": 7, @@ -162,7 +162,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.02941699999996672 + "duration": 0.028708999999992102 }, { "input": [ @@ -179,7 +179,7 @@ "name": "Example 2", "actual": 2.5, "passed": true, - "duration": 0.004042000000026746 + "duration": 0.005291999999997188 }, { "input": [ @@ -196,7 +196,7 @@ "name": "Extended Example 1", "actual": 0, "passed": true, - "duration": 0.003917000000001281 + "duration": 0.0038339999999834617 }, { "input": [ @@ -209,7 +209,7 @@ "name": "Extended Example 2", "actual": 1, "passed": true, - "duration": 0.0020420000000171967 + "duration": 0.0020419999999603533 }, { "input": [ @@ -222,7 +222,7 @@ "name": "Extended Example 3", "actual": 2, "passed": true, - "duration": 0.002999999999985903 + "duration": 0.002082999999970525 }, { "input": [ @@ -245,7 +245,7 @@ "name": "Extended Example 4", "actual": 5.5, "passed": true, - "duration": 0.0116249999999809 + "duration": 0.009165999999993346 }, { "input": [ @@ -262,7 +262,7 @@ "name": "Extended Example 5", "actual": 3, "passed": true, - "duration": 0.0027919999999994616 + "duration": 0.0027499999999918145 } ], "totalTests": 7, diff --git a/apps/site/src/data/problems/sqrt-x.json b/apps/site/src/data/problems/sqrt-x.json index 7a38fe4..0d57b28 100644 --- a/apps/site/src/data/problems/sqrt-x.json +++ b/apps/site/src/data/problems/sqrt-x.json @@ -25,7 +25,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.03654199999999719 + "duration": 0.039166000000022905 }, { "input": [ @@ -35,7 +35,7 @@ "name": "Example 2", "actual": 2, "passed": true, - "duration": 0.003207999999972344 + "duration": 0.002957999999978256 }, { "input": [ @@ -55,7 +55,7 @@ "name": "Extended Example 2", "actual": 5, "passed": true, - "duration": 0.001125000000001819 + "duration": 0.0010839999999916472 }, { "input": [ @@ -65,7 +65,7 @@ "name": "Extended Example 3", "actual": 0, "passed": true, - "duration": 0.060625000000015916 + "duration": 0.05720800000000281 }, { "input": [ @@ -85,7 +85,7 @@ "name": "Extended Example 5", "actual": 1, "passed": true, - "duration": 0.0009579999999687061 + "duration": 0.0010419999999840002 }, { "input": [ @@ -119,7 +119,7 @@ "name": "Example 1", "actual": 2, "passed": true, - "duration": 0.01704100000000608 + "duration": 0.0362920000000031 }, { "input": [ @@ -129,7 +129,7 @@ "name": "Example 2", "actual": 2, "passed": true, - "duration": 0.0015000000000213731 + "duration": 0.0019159999999942556 }, { "input": [ @@ -139,7 +139,7 @@ "name": "Extended Example 1", "actual": 4, "passed": true, - "duration": 0.0027919999999994616 + "duration": 0.0032910000000470063 }, { "input": [ @@ -159,7 +159,7 @@ "name": "Extended Example 3", "actual": 0, "passed": true, - "duration": 0.0020410000000197215 + "duration": 0.0009999999999763531 }, { "input": [ @@ -169,7 +169,7 @@ "name": "Extended Example 4", "actual": 3, "passed": true, - "duration": 0.0010839999999916472 + "duration": 0.001082999999994172 }, { "input": [ @@ -179,7 +179,7 @@ "name": "Extended Example 5", "actual": 1, "passed": true, - "duration": 0.0009590000000230248 + "duration": 0.0010000000000331966 }, { "input": [ @@ -189,7 +189,7 @@ "name": "Extended Example 6", "actual": 1, "passed": true, - "duration": 0.0007909999999924366 + "duration": 0.0007919999999899119 } ], "totalTests": 8, diff --git a/apps/site/src/data/problems/two-sum.json b/apps/site/src/data/problems/two-sum.json index 2bdd906..76d246b 100644 --- a/apps/site/src/data/problems/two-sum.json +++ b/apps/site/src/data/problems/two-sum.json @@ -37,7 +37,7 @@ 1 ], "passed": true, - "duration": 0.1588750000000232 + "duration": 0.16341699999998127 }, { "input": [ @@ -58,7 +58,7 @@ 2 ], "passed": true, - "duration": 0.09170899999998028 + "duration": 0.013166999999953077 }, { "input": [ @@ -78,7 +78,7 @@ 1 ], "passed": true, - "duration": 0.016000000000019554 + "duration": 0.057249999999953616 }, { "input": [ @@ -106,7 +106,7 @@ 9 ], "passed": true, - "duration": 0.0160420000000272 + "duration": 0.016665999999986525 }, { "input": [ @@ -134,7 +134,7 @@ 9 ], "passed": true, - "duration": 0.011916999999982636 + "duration": 0.012291000000004715 }, { "input": [ @@ -162,7 +162,7 @@ 1 ], "passed": true, - "duration": 0.06483400000001893 + "duration": 0.09458300000000008 } ], "totalTests": 6, @@ -198,7 +198,7 @@ 1 ], "passed": true, - "duration": 0.048292000000003554 + "duration": 0.05099999999998772 }, { "input": [ @@ -219,7 +219,7 @@ 2 ], "passed": true, - "duration": 0.00454199999995808 + "duration": 0.004625000000032742 }, { "input": [ @@ -239,7 +239,7 @@ 1 ], "passed": true, - "duration": 0.003666000000009717 + "duration": 0.0034999999999740794 }, { "input": [ @@ -267,7 +267,7 @@ 9 ], "passed": true, - "duration": 0.10108300000001691 + "duration": 0.009542000000010376 }, { "input": [ @@ -295,7 +295,7 @@ 9 ], "passed": true, - "duration": 0.006041999999979453 + "duration": 0.007958999999971184 }, { "input": [ @@ -323,7 +323,7 @@ 1 ], "passed": true, - "duration": 0.006791000000021086 + "duration": 0.007000000000005002 } ], "totalTests": 6, diff --git a/apps/site/src/data/problems/valid-parentheses.json b/apps/site/src/data/problems/valid-parentheses.json index 1f57d87..731a5cb 100644 --- a/apps/site/src/data/problems/valid-parentheses.json +++ b/apps/site/src/data/problems/valid-parentheses.json @@ -25,7 +25,7 @@ "name": "Example 1", "actual": true, "passed": true, - "duration": 0.058207999999979165 + "duration": 0.07254100000000108 }, { "input": [ @@ -35,7 +35,7 @@ "name": "Example 2", "actual": true, "passed": true, - "duration": 0.005084000000010747 + "duration": 0.005916999999953987 }, { "input": [ @@ -45,7 +45,7 @@ "name": "Example 3", "actual": false, "passed": true, - "duration": 0.006542000000024473 + "duration": 0.006957999999997355 }, { "input": [ @@ -55,7 +55,7 @@ "name": "Example 4", "actual": true, "passed": true, - "duration": 0.0040840000000343935 + "duration": 0.004415999999991982 }, { "input": [ @@ -65,7 +65,7 @@ "name": "Example 5", "actual": false, "passed": true, - "duration": 0.0013749999999959073 + "duration": 0.0014579999999568827 } ], "totalTests": 5, diff --git a/problems/0104-maximum-depth-of-binary-tree.ts b/problems/0104-maximum-depth-of-binary-tree.ts index 3c0dbf9..9297c8e 100644 --- a/problems/0104-maximum-depth-of-binary-tree.ts +++ b/problems/0104-maximum-depth-of-binary-tree.ts @@ -6,7 +6,7 @@ * * Description: * Given the `root` of a binary tree, return _its maximum depth_. - * + * * A binary tree's **maximum depth** is the number of nodes along the longest path from the root node down to the farthest leaf node. * * Examples: @@ -24,28 +24,118 @@ import { z } from 'zod'; import type { TestCase } from '../packages/src/types.js'; +export class TreeNode { + val: number; + left: TreeNode | null; + right: TreeNode | null; + constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + this.val = val ?? 0; + this.left = left ?? null; + this.right = right ?? null; + } +} + +export const TreeNodeSchema = z + .instanceof(TreeNode) + .check( + z.property('val', z.number()), + z.property('left', z.lazy(() => TreeNodeSchema).nullable()), + z.property('right', z.lazy(() => TreeNodeSchema).nullable()) + ); + export const SolutionSchema = z.function({ - input: [z.any()], - output: z.number() + input: [TreeNodeSchema.nullable()], + output: z.number(), }); export type Solution = z.infer; +const arrayToTreeNode = (array: (number | null)[]): TreeNode => { + if (array.length === 0) { + throw new Error('Array is empty'); + } + const root = new TreeNode(array[0]!); + const queue: (TreeNode | null)[] = [root]; + + for (let index = 1; index < array.length + 1; index += 2) { + const node = queue.shift(); + if (node) { + node.left = array[index] ? new TreeNode(array[index]!) : null; + queue.push(node.left); + if (index + 1 < array.length) { + node.right = array[index + 1] ? new TreeNode(array[index + 1]!) : null; + queue.push(node.right); + } + } + } + return root; +}; + export const cases: TestCase[] = [ - // Add your test cases here - // { input: [/* your input values */], expected: /* expected output */, name: 'Example 1' }, + { + input: [arrayToTreeNode([3, 9, 20, null, null, 15, 7])], + expected: 3, + name: 'Example 1', + }, + { + input: [arrayToTreeNode([1, null, 2])], + expected: 2, + name: 'Example 2', + }, ]; /** - * Solution - * Approach: - * - Add your approach here - * Time Complexity: O() - * Space Complexity: O() + * Iterative Solution + * @utilities: TreeNode + * Approach: + * - Use a stack to traverse the tree iteratively + * - Track the current level and the maximum level + * - Return the maximum level + * Time Complexity: O(n) + * Space Complexity: O(h) where h is the height of the tree + */ +export const iterativeSolution = SolutionSchema.implement((root) => { + if (!root) { + return 0; + } + const stack: [TreeNode, number][] = [[root, 1]]; + let node: TreeNode | null = root; + let maxLevel = 0; + let currentLevel = 1; + while (stack.length > 0 || node !== null) { + while (node !== null) { + stack.push([node, currentLevel]); + node = node.left; + currentLevel += 1; + } + + const [currentNode, level] = stack.pop() as [TreeNode, number]; + maxLevel = Math.max(maxLevel, level); + + node = currentNode.right; + currentLevel = level + 1; + } + + return maxLevel; +}); + +/** + * Recursive Solution + * @utilities: TreeNode + * Approach: + * - Use a recursive function to traverse the tree + * - Return the maximum depth of the left and right subtrees + * - Return the maximum depth of the tree + * Time Complexity: O(n) + * Space Complexity: O(h) where h is the height of the tree */ -export const solution = SolutionSchema.implement((root) => { - // Your solution here - throw new Error('Not implemented'); +export const recursiveSolution = SolutionSchema.implement((root) => { + if (!root) { + return 0; + } + return ( + 1 + Math.max(recursiveSolution(root.left), recursiveSolution(root.right)) + ); }); -export const solutions = [solution]; +export const solutions = [iterativeSolution, recursiveSolution]; diff --git a/problems/0104-maximum-depth-of-binary-tree.ts_backup b/problems/0104-maximum-depth-of-binary-tree.ts_backup deleted file mode 100644 index 6349fc1..0000000 --- a/problems/0104-maximum-depth-of-binary-tree.ts_backup +++ /dev/null @@ -1,140 +0,0 @@ -/** - * 0104. Maximum Depth of Binary Tree - * - * Difficulty: easy - * Tags: tree, depth-first-search, breadth-first-search, binary-tree - * - * Description: - * Given the `root` of a binary tree, return _its maximum depth_. - * - * A binary tree's **maximum depth** is the number of nodes along the longest path from the root node down to the farthest leaf node. - * - * Examples: - * 1. Input: root = \[3,9,20,null,null,15,7\] - * Output: 3 - * 2. Input: root = \[1,null,2\] - * Output: 2 - * - * Constraints: - * - The number of nodes in the tree is in the range `[0, 10^4]`. - * - `-100 <= Node.val <= 100` - * - */ -import { z } from 'zod'; -import type { TestCase } from '../packages/src/types.js'; - -export class TreeNode { - val: number; - left: TreeNode | null; - right: TreeNode | null; - constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { - this.val = val ?? 0; - this.left = left ?? null; - this.right = right ?? null; - } -} - -export const TreeNodeSchema = z - .instanceof(TreeNode) - .check( - z.property('val', z.number()), - z.property('left', z.lazy(() => TreeNodeSchema).nullable()), - z.property('right', z.lazy(() => TreeNodeSchema).nullable()) - ); - -export const SolutionSchema = z.function({ - input: [TreeNodeSchema.nullable()], - output: z.number(), -}); - -export type Solution = z.infer; - -const arrayToTreeNode = (array: (number | null)[]): TreeNode => { - if (array.length === 0) { - throw new Error('Array is empty'); - } - const root = new TreeNode(array[0]!); - const queue: (TreeNode | null)[] = [root]; - - for (let index = 1; index < array.length + 1; index += 2) { - const node = queue.shift(); - if (node) { - node.left = array[index] ? new TreeNode(array[index]!) : null; - queue.push(node.left); - if (index + 1 < array.length) { - node.right = array[index + 1] ? new TreeNode(array[index + 1]!) : null; - queue.push(node.right); - } - } - } - return root; -}; - -export const cases: TestCase[] = [ - { - input: [arrayToTreeNode([3, 9, 20, null, null, 15, 7])], - expected: 3, - name: 'Example 1', - }, - { - input: [arrayToTreeNode([1, null, 2])], - expected: 2, - name: 'Example 2', - }, -]; - -/** - * Iterative Solution - * @utilities: TreeNode - * Approach: - * - Use a stack to traverse the tree iteratively - * - Track the current level and the maximum level - * - Return the maximum level - * Time Complexity: O(n) - * Space Complexity: O(h) where h is the height of the tree - */ -export const iterativeSolution = SolutionSchema.implement((root) => { - if (!root) { - return 0; - } - const stack: [TreeNode, number][] = [[root, 1]]; - let node: TreeNode | null = root; - let maxLevel = 0; - let currentLevel = 1; - while (stack.length > 0 || node !== null) { - while (node !== null) { - stack.push([node, currentLevel]); - node = node.left; - currentLevel += 1; - } - - const [currentNode, level] = stack.pop() as [TreeNode, number]; - maxLevel = Math.max(maxLevel, level); - - node = currentNode.right; - currentLevel = level + 1; - } - - return maxLevel; -}); - -/** - * Recursive Solution - * @utilities: TreeNode - * Approach: - * - Use a recursive function to traverse the tree - * - Return the maximum depth of the left and right subtrees - * - Return the maximum depth of the tree - * Time Complexity: O(n) - * Space Complexity: O(h) where h is the height of the tree - */ -export const recursiveSolution = SolutionSchema.implement((root) => { - if (!root) { - return 0; - } - return ( - 1 + Math.max(recursiveSolution(root.left), recursiveSolution(root.right)) - ); -}); - -export const solutions = [iterativeSolution, recursiveSolution];