Skip to content

Commit 83247bb

Browse files
committed
feat: add more problems
1 parent 297a91c commit 83247bb

File tree

8 files changed

+321
-7
lines changed

8 files changed

+321
-7
lines changed

.amazonq/rules/problem-creation.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@ When user requests a problem by **number** or **name/slug**, the assistant will:
66

77
1. **Scrape** problem data using `.templates/leetcode/scrape.py`
88
2. **Transform** data into proper JSON template format
9-
3. **Create** JSON file in `.templates/leetcode/json/{problem_name}.json`
10-
4. **Update** Makefile with `PROBLEM ?= {problem_name}`
11-
5. **Generate** problem structure using `make p-gen`
12-
6. **Verify** with `make lint` - fix template issues in JSON if possible, or manually fix generated files if template limitations
13-
7. **Iterate** if JSON fixes: re-run `make p-gen PROBLEM={problem_name} FORCE=1` and `make lint` until passes to ensure reproducibility
9+
3. **CRITICAL: Include images** - Extract image URLs from scraped data and add to readme_examples with format: `![Example N](image_url)\n\n` before code blocks
10+
- Check scraped data for image URLs in the `raw_content` field
11+
- Look for patterns: `https://assets.leetcode.com/uploads/...` or `<img alt="" src="..." />`
12+
- Common patterns: `kthtree1.jpg`, `kthtree2.jpg`, `clone_graph.png`, `container.jpg`
13+
- Images provide crucial visual context, especially for tree and graph problems
14+
- Always verify images are included in `readme_examples` and accessible
15+
4. **Create** JSON file in `.templates/leetcode/json/{problem_name}.json`
16+
5. **Update** Makefile with `PROBLEM ?= {problem_name}`
17+
6. **Generate** problem structure using `make p-gen`
18+
7. **Verify** with `make lint` - fix template issues in JSON if possible, or manually fix generated files if template limitations
19+
8. **Iterate** if JSON fixes: re-run `make p-gen PROBLEM={problem_name} FORCE=1` and `make lint` until passes to ensure reproducibility
1420

1521
## Scraping Commands
1622

@@ -46,7 +52,7 @@ Required fields for `.templates/leetcode/json/{problem_name}.json`:
4652
"readme_description": "Given an array of integers `nums` and an integer `target`, return indices of the two numbers such that they add up to `target`.",
4753
"readme_examples": [
4854
{
49-
"content": "```\nInput: nums = [2,7,11,15], target = 9\nOutput: [0,1]\n```\n**Explanation:** Because nums[0] + nums[1] == 9, we return [0, 1]."
55+
"content": "![Example 1](https://example.com/image1.jpg)\n\n```\nInput: nums = [2,7,11,15], target = 9\nOutput: [0,1]\n```\n**Explanation:** Because nums[0] + nums[1] == 9, we return [0, 1]."
5056
}
5157
],
5258
"readme_constraints": "- 2 <= nums.length <= 10^4\n- -10^9 <= nums[i] <= 10^9\n- -10^9 <= target <= 10^9\n- Only one valid answer exists.",
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"problem_name": "kth_smallest_element_in_a_bst",
3+
"solution_class_name": "Solution",
4+
"problem_number": "230",
5+
"problem_title": "Kth Smallest Element in a BST",
6+
"difficulty": "Medium",
7+
"topics": "Tree, Depth-First Search, Binary Search Tree, Binary Tree",
8+
"tags": [],
9+
"readme_description": "Given the `root` of a binary search tree, and an integer `k`, return the `k`th smallest value (1-indexed) of all the values of the nodes in the tree.",
10+
"readme_examples": [
11+
{
12+
"content": "![Example 1](https://assets.leetcode.com/uploads/2021/01/28/kthtree1.jpg)\n\n```\nInput: root = [3,1,4,null,2], k = 1\nOutput: 1\n```"
13+
},
14+
{
15+
"content": "![Example 2](https://assets.leetcode.com/uploads/2021/01/28/kthtree2.jpg)\n\n```\nInput: root = [5,3,6,2,4,null,null,1], k = 3\nOutput: 3\n```"
16+
}
17+
],
18+
"readme_constraints": "- The number of nodes in the tree is `n`.\n- `1 <= k <= n <= 10^4`\n- `0 <= Node.val <= 10^4`",
19+
"readme_additional": "**Follow up:** If the BST is modified often (i.e., we can do insert and delete operations) and you need to find the kth smallest frequently, how would you optimize?",
20+
"solution_imports": "from leetcode_py import TreeNode",
21+
"solution_methods": [
22+
{
23+
"name": "kth_smallest",
24+
"parameters": "root: TreeNode | None, k: int",
25+
"return_type": "int",
26+
"dummy_return": "0"
27+
}
28+
],
29+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom leetcode_py import TreeNode\nfrom .solution import Solution",
30+
"test_class_name": "KthSmallestElementInABst",
31+
"test_helper_methods": [
32+
{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }
33+
],
34+
"test_methods": [
35+
{
36+
"name": "test_kth_smallest",
37+
"parametrize": "root_list, k, expected",
38+
"parametrize_typed": "root_list: list[int | None], k: int, expected: int",
39+
"test_cases": "[([3, 1, 4, None, 2], 1, 1), ([5, 3, 6, 2, 4, None, None, 1], 3, 3), ([1], 1, 1)]",
40+
"body": "root = TreeNode.from_list(root_list)\nresult = self.solution.kth_smallest(root, k)\nassert result == expected"
41+
}
42+
],
43+
"playground_imports": "from solution import Solution\nfrom leetcode_py import TreeNode",
44+
"playground_test_case": "# Example test case\nroot_list = [3, 1, 4, None, 2]\nk = 1\nexpected = 1",
45+
"playground_execution": "root = TreeNode.from_list(root_list)\nresult = Solution().kth_smallest(root, k)\nresult",
46+
"playground_assertion": "assert result == expected"
47+
}

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
PYTHON_VERSION = 3.13
2-
PROBLEM ?= task_scheduler
2+
PROBLEM ?= kth_smallest_element_in_a_bst
33
FORCE ?= 0
44

55
sync_submodules:
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Kth Smallest Element in a BST
2+
3+
**Difficulty:** Medium
4+
**Topics:** Tree, Depth-First Search, Binary Search Tree, Binary Tree
5+
**Tags:**
6+
7+
**LeetCode:** [Problem 230](https://leetcode.com/problems/kth-smallest-element-in-a-bst/description/)
8+
9+
## Problem Description
10+
11+
Given the `root` of a binary search tree, and an integer `k`, return the `k`th smallest value (1-indexed) of all the values of the nodes in the tree.
12+
13+
## Examples
14+
15+
### Example 1:
16+
17+
![Example 1](https://assets.leetcode.com/uploads/2021/01/28/kthtree1.jpg)
18+
19+
```
20+
Input: root = [3,1,4,null,2], k = 1
21+
Output: 1
22+
```
23+
24+
### Example 2:
25+
26+
![Example 2](https://assets.leetcode.com/uploads/2021/01/28/kthtree2.jpg)
27+
28+
```
29+
Input: root = [5,3,6,2,4,null,null,1], k = 3
30+
Output: 3
31+
```
32+
33+
## Constraints
34+
35+
- The number of nodes in the tree is `n`.
36+
- `1 <= k <= n <= 10^4`
37+
- `0 <= Node.val <= 10^4`
38+
39+
**Follow up:** If the BST is modified often (i.e., we can do insert and delete operations) and you need to find the kth smallest frequently, how would you optimize?

leetcode/kth_smallest_element_in_a_bst/__init__.py

Whitespace-only changes.
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 1,
6+
"id": "imports",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"from solution import Solution\n",
11+
"\n",
12+
"from leetcode_py import TreeNode"
13+
]
14+
},
15+
{
16+
"cell_type": "code",
17+
"execution_count": 2,
18+
"id": "setup",
19+
"metadata": {},
20+
"outputs": [],
21+
"source": [
22+
"# Example test case\n",
23+
"root_list = [3, 1, 4, None, 2]\n",
24+
"k = 1\n",
25+
"expected = 1"
26+
]
27+
},
28+
{
29+
"cell_type": "code",
30+
"execution_count": 3,
31+
"id": "execute",
32+
"metadata": {},
33+
"outputs": [
34+
{
35+
"data": {
36+
"text/plain": [
37+
"1"
38+
]
39+
},
40+
"execution_count": 3,
41+
"metadata": {},
42+
"output_type": "execute_result"
43+
}
44+
],
45+
"source": [
46+
"root = TreeNode.from_list(root_list)\n",
47+
"result = Solution().kth_smallest(root, k)\n",
48+
"result"
49+
]
50+
},
51+
{
52+
"cell_type": "code",
53+
"execution_count": 4,
54+
"id": "6dc42838",
55+
"metadata": {},
56+
"outputs": [
57+
{
58+
"data": {
59+
"text/html": [
60+
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
61+
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
62+
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
63+
"<!-- Generated by graphviz version 13.1.2 (20250808.2320)\n",
64+
" -->\n",
65+
"<!-- Pages: 1 -->\n",
66+
"<svg width=\"134pt\" height=\"188pt\"\n",
67+
" viewBox=\"0.00 0.00 134.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
68+
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n",
69+
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-184 130,-184 130,4 -4,4\"/>\n",
70+
"<!-- 0 -->\n",
71+
"<g id=\"node1\" class=\"node\">\n",
72+
"<title>0</title>\n",
73+
"<ellipse fill=\"none\" stroke=\"black\" cx=\"63\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
74+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"63\" y=\"-156.95\" font-family=\"Times,serif\" font-size=\"14.00\">3</text>\n",
75+
"</g>\n",
76+
"<!-- 1 -->\n",
77+
"<g id=\"node2\" class=\"node\">\n",
78+
"<title>1</title>\n",
79+
"<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
80+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"27\" y=\"-84.95\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
81+
"</g>\n",
82+
"<!-- 0&#45;&gt;1 -->\n",
83+
"<g id=\"edge1\" class=\"edge\">\n",
84+
"<title>0&#45;&gt;1</title>\n",
85+
"<path fill=\"none\" stroke=\"black\" d=\"M54.65,-144.76C50.42,-136.55 45.19,-126.37 40.42,-117.09\"/>\n",
86+
"<polygon fill=\"black\" stroke=\"black\" points=\"43.68,-115.79 36,-108.49 37.46,-118.99 43.68,-115.79\"/>\n",
87+
"</g>\n",
88+
"<!-- 3 -->\n",
89+
"<g id=\"node4\" class=\"node\">\n",
90+
"<title>3</title>\n",
91+
"<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
92+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"99\" y=\"-84.95\" font-family=\"Times,serif\" font-size=\"14.00\">4</text>\n",
93+
"</g>\n",
94+
"<!-- 0&#45;&gt;3 -->\n",
95+
"<g id=\"edge3\" class=\"edge\">\n",
96+
"<title>0&#45;&gt;3</title>\n",
97+
"<path fill=\"none\" stroke=\"black\" d=\"M71.35,-144.76C75.58,-136.55 80.81,-126.37 85.58,-117.09\"/>\n",
98+
"<polygon fill=\"black\" stroke=\"black\" points=\"88.54,-118.99 90,-108.49 82.32,-115.79 88.54,-118.99\"/>\n",
99+
"</g>\n",
100+
"<!-- 2 -->\n",
101+
"<g id=\"node3\" class=\"node\">\n",
102+
"<title>2</title>\n",
103+
"<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
104+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"27\" y=\"-12.95\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n",
105+
"</g>\n",
106+
"<!-- 1&#45;&gt;2 -->\n",
107+
"<g id=\"edge2\" class=\"edge\">\n",
108+
"<title>1&#45;&gt;2</title>\n",
109+
"<path fill=\"none\" stroke=\"black\" d=\"M27,-71.7C27,-64.41 27,-55.73 27,-47.54\"/>\n",
110+
"<polygon fill=\"black\" stroke=\"black\" points=\"30.5,-47.62 27,-37.62 23.5,-47.62 30.5,-47.62\"/>\n",
111+
"</g>\n",
112+
"</g>\n",
113+
"</svg>\n"
114+
],
115+
"text/plain": [
116+
"TreeNode([3, 1, 4, None, 2])"
117+
]
118+
},
119+
"execution_count": 4,
120+
"metadata": {},
121+
"output_type": "execute_result"
122+
}
123+
],
124+
"source": [
125+
"root"
126+
]
127+
},
128+
{
129+
"cell_type": "code",
130+
"execution_count": 5,
131+
"id": "test",
132+
"metadata": {},
133+
"outputs": [],
134+
"source": [
135+
"assert result == expected"
136+
]
137+
}
138+
],
139+
"metadata": {
140+
"kernelspec": {
141+
"display_name": "leetcode-py-py3.13",
142+
"language": "python",
143+
"name": "python3"
144+
},
145+
"language_info": {
146+
"codemirror_mode": {
147+
"name": "ipython",
148+
"version": 3
149+
},
150+
"file_extension": ".py",
151+
"mimetype": "text/x-python",
152+
"name": "python",
153+
"nbconvert_exporter": "python",
154+
"pygments_lexer": "ipython3",
155+
"version": "3.13.7"
156+
}
157+
},
158+
"nbformat": 4,
159+
"nbformat_minor": 5
160+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from leetcode_py import TreeNode
2+
3+
4+
class Solution:
5+
# Inorder Recursive
6+
# Time: O(k)
7+
# Space: O(h)
8+
def kth_smallest(self, root: TreeNode | None, k: int) -> int:
9+
def inorder(node: TreeNode | None):
10+
if not node:
11+
return
12+
yield from inorder(node.left)
13+
yield node.val
14+
yield from inorder(node.right)
15+
16+
for i, val in enumerate(inorder(root)):
17+
if i == k - 1:
18+
return val
19+
20+
raise ValueError(f"Tree has fewer than {k} nodes")
21+
22+
23+
# Binary Tree Traversal Patterns
24+
#
25+
# def inorder(node):
26+
# if node:
27+
# inorder(node.left)
28+
# print(node.val)
29+
# inorder(node.right)
30+
#
31+
# def preorder(node):
32+
# if node:
33+
# print(node.val)
34+
# preorder(node.left)
35+
# preorder(node.right)
36+
#
37+
# def postorder(node):
38+
# if node:
39+
# postorder(node.left)
40+
# postorder(node.right)
41+
# print(node.val)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import pytest
2+
3+
from leetcode_py import TreeNode
4+
from leetcode_py.test_utils import logged_test
5+
6+
from .solution import Solution
7+
8+
9+
class TestKthSmallestElementInABst:
10+
def setup_method(self):
11+
self.solution = Solution()
12+
13+
@pytest.mark.parametrize(
14+
"root_list, k, expected",
15+
[([3, 1, 4, None, 2], 1, 1), ([5, 3, 6, 2, 4, None, None, 1], 3, 3), ([1], 1, 1)],
16+
)
17+
@logged_test
18+
def test_kth_smallest(self, root_list: list[int | None], k: int, expected: int):
19+
root = TreeNode.from_list(root_list)
20+
result = self.solution.kth_smallest(root, k)
21+
assert result == expected

0 commit comments

Comments
 (0)