Skip to content

Commit 816db0a

Browse files
committed
feat: add more problems
1 parent 4e259b5 commit 816db0a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1748
-60
lines changed

.amazonq/plans/create_template_example.md

Lines changed: 0 additions & 51 deletions
This file was deleted.

.amazonq/plans/migrate_problems_to_new_template.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,24 @@ Migrate problems from `.templates/leetcode/json_old/` to `.templates/leetcode/js
44

55
## Migration Steps
66

7+
**Note**: Commands require UI confirmation popup - click "Run" when prompted for `make` commands.
8+
79
1. **Create JSON**: Analyze old format, create new template in `.templates/leetcode/json/` (reference `.templates/leetcode/examples/` for format)
810
2. **Generate**: `make p-gen PROBLEM=<name>`
911
3. **Lint**: `make p-lint PROBLEM=<name>` (fix JSON if fails, regenerate with `FORCE=1`)
10-
4. **Implement**: Look at `leetcode_old/` code - copy solution with all comments/notes and review test cases
11-
- **Important**: Re-copy solution after `p-gen` since it overwrites with TODO placeholders
12-
- **Multiple solutions**: If old code has alternative implementations (e.g., Solution, SolutionDFS, SolutionBFS),
13-
add parametrize to test all classes (see lru_cache as example)
14-
5. **Test**: `make p-test PROBLEM=<name>`
15-
6. **Enhance tests**: Review test coverage - check if cases cover edge scenarios:
12+
4. **Enhance tests**: Review test coverage - check if cases cover edge scenarios:
13+
- **Check old tests**: Examine `leetcode_old/<problem>/tests.py` for comprehensive test coverage
14+
- **Update JSON**: Add relevant/generalizable test cases to JSON template (exclude problem-specific error handling)
1615
- Boundary values (min/max constraints, empty inputs)
1716
- Different input sizes/lengths
1817
- Zero/null cases, single elements
1918
- Error conditions, special values
2019
- If only 2-3 basic cases, add comprehensive edge cases (update JSON → regenerate with `FORCE=1` → lint → re-copy solution → test)
20+
5. **Implement**: Look at `leetcode_old/` code - copy solution with all comments/notes
21+
- **Important**: Re-copy solution after `p-gen` since it overwrites with TODO placeholders
22+
- **Multiple solutions**: If old code has alternative implementations (e.g., Solution, SolutionDFS, SolutionBFS),
23+
add parametrize to test all classes (see lru_cache as example)
24+
6. **Test**: `make p-test PROBLEM=<name>` (edit JSON and revalidate for reproducibility if needed)
2125

2226
## Progress
2327

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"problem_name": "balanced_binary_tree",
3+
"solution_class_name": "Solution",
4+
"problem_number": "110",
5+
"problem_title": "Balanced Binary Tree",
6+
"difficulty": "Easy",
7+
"topics": "Tree, Depth-First Search, Binary Tree",
8+
"_tags": { "list": ["grind-75"] },
9+
"readme_description": "Given a binary tree, determine if it is **height-balanced**.\n\nA height-balanced binary tree is a binary tree in which the depth of the two subtrees of every node never differs by more than one.",
10+
"_readme_examples": {
11+
"list": [
12+
{
13+
"content": "![Example 1](https://assets.leetcode.com/uploads/2020/10/06/balance_1.jpg)\n\n```\nInput: root = [3,9,20,null,null,15,7]\nOutput: true\n```"
14+
},
15+
{
16+
"content": "![Example 2](https://assets.leetcode.com/uploads/2020/10/06/balance_2.jpg)\n\n```\nInput: root = [1,2,2,3,3,null,null,4,4]\nOutput: false\n```"
17+
},
18+
{ "content": "```\nInput: root = []\nOutput: true\n```" }
19+
]
20+
},
21+
"readme_constraints": "- The number of nodes in the tree is in the range `[0, 5000]`.\n- `-10^4 <= Node.val <= 10^4`",
22+
"readme_additional": "",
23+
"helpers_imports": "from leetcode_py import TreeNode",
24+
"helpers_content": "",
25+
"helpers_run_name": "is_balanced",
26+
"helpers_run_signature": "(solution_class: type, root_list: list[int | None])",
27+
"helpers_run_body": " implementation = solution_class()\n root = TreeNode.from_list(root_list)\n return implementation.is_balanced(root)",
28+
"helpers_assert_name": "is_balanced",
29+
"helpers_assert_signature": "(result: bool, expected: bool) -> bool",
30+
"helpers_assert_body": " assert result == expected\n return True",
31+
"solution_imports": "from leetcode_py import TreeNode",
32+
"solution_contents": "",
33+
"solution_class_content": "",
34+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .helpers import assert_is_balanced, run_is_balanced\nfrom .solution import Solution",
35+
"test_content": "",
36+
"test_class_name": "BalancedBinaryTree",
37+
"test_class_content": " def setup_method(self):\n self.solution = Solution()",
38+
"_solution_methods": {
39+
"list": [
40+
{
41+
"name": "is_balanced",
42+
"signature": "(self, root: TreeNode[int] | None) -> bool",
43+
"body": " # TODO: Implement is_balanced\n return False"
44+
}
45+
]
46+
},
47+
"_test_helper_methods": {
48+
"list": [{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }]
49+
},
50+
"_test_methods": {
51+
"list": [
52+
{
53+
"name": "test_is_balanced",
54+
"signature": "(self, root_list: list[int | None], expected: bool)",
55+
"parametrize": "root_list, expected",
56+
"test_cases": "[([3, 9, 20, None, None, 15, 7], True), ([1, 2, 2, 3, 3, None, None, 4, 4], False), ([], True), ([1], True), ([1, 2], True), ([1, None, 2], True), ([1, 2, 3, 4], True), ([1, 2, 2, 3, None, None, 3, 4, None, None, 4], False)]",
57+
"body": " result = run_is_balanced(Solution, root_list)\n assert_is_balanced(result, expected)"
58+
}
59+
]
60+
},
61+
"playground_imports": "from helpers import run_is_balanced, assert_is_balanced\nfrom solution import Solution\nfrom leetcode_py import TreeNode",
62+
"playground_setup": "# Example test case\nroot_list: list[int | None] = [3, 9, 20, None, None, 15, 7]\nexpected = True",
63+
"playground_run": "result = run_is_balanced(Solution, root_list)\nresult",
64+
"playground_assert": "assert_is_balanced(result, expected)"
65+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"problem_name": "basic_calculator",
3+
"solution_class_name": "Solution",
4+
"problem_number": "224",
5+
"problem_title": "Basic Calculator",
6+
"difficulty": "Hard",
7+
"topics": "Math, String, Stack, Recursion",
8+
"_tags": { "list": ["grind-75"] },
9+
"readme_description": "Given a string `s` representing a valid expression, implement a basic calculator to evaluate it, and return the result of the evaluation.\n\n**Note:** You are **not** allowed to use any built-in function which evaluates strings as mathematical expressions, such as `eval()`.",
10+
"_readme_examples": {
11+
"list": [
12+
{ "content": "```\nInput: s = \"1 + 1\"\nOutput: 2\n```" },
13+
{ "content": "```\nInput: s = \" 2-1 + 2 \"\nOutput: 3\n```" },
14+
{ "content": "```\nInput: s = \"(1+(4+5+2)-3)+(6+8)\"\nOutput: 23\n```" }
15+
]
16+
},
17+
"readme_constraints": "- `1 <= s.length <= 3 * 10^5`\n- `s` consists of digits, `'+'`, `'-'`, `'('`, `')'`, and `' '`.\n- `s` represents a valid expression.\n- `'+'` is **not** used as a unary operation (i.e., `\"+1\"` and `\"+(2 + 3)\"` is invalid).\n- `'-'` could be used as a unary operation (i.e., `\"-1\"` and `\"-(2 + 3)\"` is valid).\n- There will be no two consecutive operators in the input.\n- Every number and running calculation will fit in a signed 32-bit integer.",
18+
"readme_additional": "",
19+
"helpers_imports": "",
20+
"helpers_content": "",
21+
"helpers_run_name": "calculate",
22+
"helpers_run_signature": "(solution_class: type, s: str)",
23+
"helpers_run_body": " implementation = solution_class()\n return implementation.calculate(s)",
24+
"helpers_assert_name": "calculate",
25+
"helpers_assert_signature": "(result: int, expected: int) -> bool",
26+
"helpers_assert_body": " assert result == expected\n return True",
27+
"solution_imports": "",
28+
"solution_contents": "",
29+
"solution_class_content": "",
30+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .helpers import assert_calculate, run_calculate\nfrom .solution import Solution",
31+
"test_content": "",
32+
"test_class_name": "BasicCalculator",
33+
"test_class_content": " def setup_method(self):\n self.solution = Solution()",
34+
"_solution_methods": {
35+
"list": [
36+
{
37+
"name": "calculate",
38+
"signature": "(self, s: str) -> int",
39+
"body": " # TODO: Implement calculate\n return 0"
40+
}
41+
]
42+
},
43+
"_test_helper_methods": {
44+
"list": [{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }]
45+
},
46+
"_test_methods": {
47+
"list": [
48+
{
49+
"name": "test_calculate",
50+
"signature": "(self, s: str, expected: int)",
51+
"parametrize": "s, expected",
52+
"test_cases": "[('1 + 1', 2), (' 2-1 + 2 ', 3), ('(1+(4+5+2)-3)+(6+8)', 23), ('1', 1), ('-1', -1), ('-(1+2)', -3), ('2147483647', 2147483647), ('1-1+1', 1), ('0', 0), ('-0', 0), ('1+(2+3)', 6), ('(1+2)+3', 6), ('1-(2+3)', -4), ('(1-2)+3', 2), ('-(-1)', 1), ('-(-(-1))', -1), ('1000000-999999', 1), ('10+20-30+40', 40), ('((1+2)+(3+4))', 10), ('1+(2-(3+4))', -4), ('-(1+(2+3))', -6), (' 1 + 2 ', 3), ('123+456', 579), ('-2147483648', -2147483648)]",
53+
"body": " result = run_calculate(Solution, s)\n assert_calculate(result, expected)"
54+
}
55+
]
56+
},
57+
"playground_imports": "from helpers import run_calculate, assert_calculate\nfrom solution import Solution",
58+
"playground_setup": "# Example test case\ns = '(1+(4+5+2)-3)+(6+8)'\nexpected = 23",
59+
"playground_run": "result = run_calculate(Solution, s)\nresult",
60+
"playground_assert": "assert_calculate(result, expected)"
61+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
"problem_name": "best_time_to_buy_and_sell_stock",
3+
"solution_class_name": "Solution",
4+
"problem_number": "121",
5+
"problem_title": "Best Time to Buy and Sell Stock",
6+
"difficulty": "Easy",
7+
"topics": "Array, Dynamic Programming",
8+
"_tags": { "list": ["grind-75"] },
9+
"readme_description": "You are given an array `prices` where `prices[i]` is the price of a given stock on the ith day.\n\nYou want to maximize your profit by choosing a **single day** to buy one stock and choosing a **different day in the future** to sell that stock.\n\nReturn *the maximum profit you can achieve from this transaction*. If you cannot achieve any profit, return `0`.",
10+
"_readme_examples": {
11+
"list": [
12+
{
13+
"content": "```\nInput: prices = [7,1,5,3,6,4]\nOutput: 5\n```\n**Explanation:** Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.\nNote that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell."
14+
},
15+
{
16+
"content": "```\nInput: prices = [7,6,4,3,1]\nOutput: 0\n```\n**Explanation:** In this case, no transactions are done and the max profit = 0."
17+
}
18+
]
19+
},
20+
"readme_constraints": "- 1 <= prices.length <= 10^5\n- 0 <= prices[i] <= 10^4",
21+
"readme_additional": "",
22+
"helpers_imports": "",
23+
"helpers_content": "",
24+
"helpers_run_name": "max_profit",
25+
"helpers_run_signature": "(solution_class: type, prices: list[int])",
26+
"helpers_run_body": " implementation = solution_class()\n return implementation.max_profit(prices)",
27+
"helpers_assert_name": "max_profit",
28+
"helpers_assert_signature": "(result: int, expected: int) -> bool",
29+
"helpers_assert_body": " assert result == expected\n return True",
30+
"solution_imports": "",
31+
"solution_contents": "",
32+
"solution_class_content": "",
33+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .helpers import assert_max_profit, run_max_profit\nfrom .solution import Solution",
34+
"test_content": "",
35+
"test_class_name": "BestTimeToBuyAndSellStock",
36+
"test_class_content": " def setup_method(self):\n self.solution = Solution()",
37+
"_solution_methods": {
38+
"list": [
39+
{
40+
"name": "max_profit",
41+
"signature": "(self, prices: list[int]) -> int",
42+
"body": " # TODO: Implement max_profit\n return 0"
43+
}
44+
]
45+
},
46+
"_test_helper_methods": {
47+
"list": [{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }]
48+
},
49+
"_test_methods": {
50+
"list": [
51+
{
52+
"name": "test_max_profit",
53+
"signature": "(self, prices: list[int], expected: int)",
54+
"parametrize": "prices, expected",
55+
"test_cases": "[([7, 1, 5, 3, 6, 4], 5), ([7, 6, 4, 3, 1], 0), ([1, 2, 3, 4, 5], 4), ([5, 4, 3, 2, 1], 0), ([1], 0), ([2, 1], 0), ([1, 2], 1), ([3, 2, 6, 5, 0, 3], 4)]",
56+
"body": " result = run_max_profit(Solution, prices)\n assert_max_profit(result, expected)"
57+
}
58+
]
59+
},
60+
"playground_imports": "from helpers import run_max_profit, assert_max_profit\nfrom solution import Solution",
61+
"playground_setup": "# Example test case\nprices = [7, 1, 5, 3, 6, 4]\nexpected = 5",
62+
"playground_run": "result = run_max_profit(Solution, prices)\nresult",
63+
"playground_assert": "assert_max_profit(result, expected)"
64+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
"problem_name": "binary_search",
3+
"solution_class_name": "Solution",
4+
"problem_number": "704",
5+
"problem_title": "Binary Search",
6+
"difficulty": "Easy",
7+
"topics": "Array, Binary Search",
8+
"_tags": { "list": ["grind-75"] },
9+
"readme_description": "Given an array of integers `nums` which is sorted in ascending order, and an integer `target`, write a function to search `target` in `nums`. If `target` exists, then return its index. Otherwise, return `-1`.\n\nYou must write an algorithm with `O(log n)` runtime complexity.",
10+
"_readme_examples": {
11+
"list": [
12+
{
13+
"content": "```\nInput: nums = [-1,0,3,5,9,12], target = 9\nOutput: 4\n```\n**Explanation:** 9 exists in nums and its index is 4"
14+
},
15+
{
16+
"content": "```\nInput: nums = [-1,0,3,5,9,12], target = 2\nOutput: -1\n```\n**Explanation:** 2 does not exist in nums so return -1"
17+
}
18+
]
19+
},
20+
"readme_constraints": "- `1 <= nums.length <= 10^4`\n- `-10^4 < nums[i], target < 10^4`\n- All the integers in `nums` are **unique**.\n- `nums` is sorted in ascending order.",
21+
"readme_additional": "",
22+
"helpers_imports": "",
23+
"helpers_content": "",
24+
"helpers_run_name": "search",
25+
"helpers_run_signature": "(solution_class: type, nums: list[int], target: int)",
26+
"helpers_run_body": " implementation = solution_class()\n return implementation.search(nums, target)",
27+
"helpers_assert_name": "search",
28+
"helpers_assert_signature": "(result: int, expected: int) -> bool",
29+
"helpers_assert_body": " assert result == expected\n return True",
30+
"solution_imports": "",
31+
"solution_contents": "",
32+
"solution_class_content": "",
33+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .helpers import assert_search, run_search\nfrom .solution import Solution",
34+
"test_content": "",
35+
"test_class_name": "BinarySearch",
36+
"test_class_content": " def setup_method(self):\n self.solution = Solution()",
37+
"_solution_methods": {
38+
"list": [
39+
{
40+
"name": "search",
41+
"signature": "(self, nums: list[int], target: int) -> int",
42+
"body": " # TODO: Implement search\n return -1"
43+
}
44+
]
45+
},
46+
"_test_helper_methods": {
47+
"list": [{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }]
48+
},
49+
"_test_methods": {
50+
"list": [
51+
{
52+
"name": "test_search",
53+
"signature": "(self, nums: list[int], target: int, expected: int)",
54+
"parametrize": "nums, target, expected",
55+
"test_cases": "[([-1, 0, 3, 5, 9, 12], 9, 4), ([-1, 0, 3, 5, 9, 12], 2, -1), ([5], 5, 0), ([5], -5, -1), ([1, 3, 5, 7, 9], 1, 0), ([1, 3, 5, 7, 9], 9, 4), ([1, 3, 5, 7, 9], 4, -1), ([1, 3], 1, 0), ([1, 3], 3, 1), ([1, 3], 2, -1), ([-5, -2, 0, 3, 7], -2, 1), ([-5, -2, 0, 3, 7], 0, 2), ([-5, -2, 0, 3, 7], -1, -1)]",
56+
"body": " result = run_search(Solution, nums, target)\n assert_search(result, expected)"
57+
}
58+
]
59+
},
60+
"playground_imports": "from helpers import run_search, assert_search\nfrom solution import Solution",
61+
"playground_setup": "# Example test case\nnums = [-1, 0, 3, 5, 9, 12]\ntarget = 9\nexpected = 4",
62+
"playground_run": "result = run_search(Solution, nums, target)\nresult",
63+
"playground_assert": "assert_search(result, expected)"
64+
}

0 commit comments

Comments
 (0)