Skip to content

Commit 297a91c

Browse files
authored
feat: add more questions (#18)
1 parent f164898 commit 297a91c

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

+2077
-13
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"problem_name": "binary_tree_right_side_view",
3+
"solution_class_name": "Solution",
4+
"problem_number": "199",
5+
"problem_title": "Binary Tree Right Side View",
6+
"difficulty": "Medium",
7+
"topics": "Tree, Depth-First Search, Breadth-First Search, Binary Tree",
8+
"tags": ["grind-75"],
9+
"readme_description": "Given the `root` of a binary tree, imagine yourself standing on the **right side** of it, return *the values of the nodes you can see ordered from top to bottom*.",
10+
"readme_examples": [
11+
{
12+
"content": "![Example 1](https://assets.leetcode.com/uploads/2024/11/24/tmpd5jn43fs-1.png)\n\n```\nInput: root = [1,2,3,null,5,null,4]\nOutput: [1,3,4]\n```"
13+
},
14+
{
15+
"content": "![Example 2](https://assets.leetcode.com/uploads/2024/11/24/tmpkpe40xeh-1.png)\n\n```\nInput: root = [1,2,3,4,null,null,null,5]\nOutput: [1,3,4,5]\n```"
16+
},
17+
{ "content": "```\nInput: root = [1,null,3]\nOutput: [1,3]\n```" },
18+
{ "content": "```\nInput: root = []\nOutput: []\n```" }
19+
],
20+
"readme_constraints": "- The number of nodes in the tree is in the range `[0, 100]`.\n- `-100 <= Node.val <= 100`",
21+
"readme_additional": "",
22+
"solution_imports": "from leetcode_py import TreeNode",
23+
"solution_methods": [
24+
{
25+
"name": "right_side_view",
26+
"parameters": "root: TreeNode[int] | None",
27+
"return_type": "list[int]",
28+
"dummy_return": "[]"
29+
}
30+
],
31+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom leetcode_py import TreeNode\nfrom .solution import Solution",
32+
"test_class_name": "BinaryTreeRightSideView",
33+
"test_helper_methods": [
34+
{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }
35+
],
36+
"test_methods": [
37+
{
38+
"name": "test_right_side_view",
39+
"parametrize": "root_list, expected",
40+
"parametrize_typed": "root_list: list[int | None], expected: list[int]",
41+
"test_cases": "[([1, 2, 3, None, 5, None, 4], [1, 3, 4]), ([1, 2, 3, 4, None, None, None, 5], [1, 3, 4, 5]), ([1, None, 3], [1, 3]), ([], [])]",
42+
"body": "root = TreeNode.from_list(root_list)\nresult = self.solution.right_side_view(root)\nassert result == expected"
43+
}
44+
],
45+
"playground_imports": "from solution import Solution\nfrom leetcode_py import TreeNode",
46+
"playground_test_case": "# Example test case\nroot_list: list[int | None] = [1, 2, 3, None, 5, None, 4]\nexpected = [1, 3, 4]",
47+
"playground_execution": "root = TreeNode.from_list(root_list)\nresult = Solution().right_side_view(root)\nresult",
48+
"playground_assertion": "assert result == expected"
49+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"problem_name": "clone_graph",
3+
"solution_class_name": "Solution",
4+
"problem_number": "133",
5+
"problem_title": "Clone Graph",
6+
"difficulty": "Medium",
7+
"topics": "Hash Table, Depth-First Search, Breadth-First Search, Graph",
8+
"tags": ["grind-75"],
9+
"readme_description": "Given a reference of a node in a **connected** undirected graph.\n\nReturn a **deep copy** (clone) of the graph.\n\nEach node in the graph contains a value (`int`) and a list (`List[Node]`) of its neighbors.\n\n```\nclass Node {\n public int val;\n public List<Node> neighbors;\n}\n```\n\n**Test case format:**\n\nFor simplicity, each node's value is the same as the node's index (1-indexed). For example, the first node with `val == 1`, the second node with `val == 2`, and so on. The graph is represented in the test case using an adjacency list.\n\n**An adjacency list** is a collection of unordered **lists** used to represent a finite graph. Each list describes the set of neighbors of a node in the graph.\n\nThe given node will always be the first node with `val = 1`. You must return the **copy of the given node** as a reference to the cloned graph.",
10+
"readme_examples": [
11+
{
12+
"content": "<img alt=\"\" src=\"https://assets.leetcode.com/uploads/2019/11/04/133_clone_graph_question.png\" style=\"width: 454px; height: 500px;\" />\n\n```\nInput: adjList = [[2,4],[1,3],[2,4],[1,3]]\nOutput: [[2,4],[1,3],[2,4],[1,3]]\nExplanation: There are 4 nodes in the graph.\n1st node (val = 1)'s neighbors are 2nd node (val = 2) and 4th node (val = 4).\n2nd node (val = 2)'s neighbors are 1st node (val = 1) and 3rd node (val = 3).\n3rd node (val = 3)'s neighbors are 2nd node (val = 2) and 4th node (val = 4).\n4th node (val = 4)'s neighbors are 1st node (val = 1) and 3rd node (val = 3).\n```"
13+
},
14+
{
15+
"content": "<img alt=\"\" src=\"https://assets.leetcode.com/uploads/2020/01/07/graph.png\" style=\"width: 163px; height: 148px;\" />\n\n```\nInput: adjList = [[]]\nOutput: [[]]\nExplanation: Note that the input contains one empty list. The graph consists of only one node with val = 1 and it does not have any neighbors.\n```"
16+
},
17+
{
18+
"content": "```\nInput: adjList = []\nOutput: []\nExplanation: This an empty graph, it does not have any nodes.\n```"
19+
}
20+
],
21+
"readme_constraints": "- The number of nodes in the graph is in the range `[0, 100]`.\n- `1 <= Node.val <= 100`\n- `Node.val` is unique for each node.\n- There are no repeated edges and no self-loops in the graph.\n- The Graph is connected and all nodes can be visited starting from the given node.",
22+
"readme_additional": "",
23+
"solution_imports": "from leetcode_py import GraphNode",
24+
"solution_methods": [
25+
{
26+
"name": "clone_graph",
27+
"parameters": "node: GraphNode | None",
28+
"return_type": "GraphNode | None",
29+
"dummy_return": "None"
30+
}
31+
],
32+
"test_imports": "import pytest\n\nfrom leetcode_py import GraphNode\nfrom leetcode_py.test_utils import logged_test\n\nfrom .solution import Solution",
33+
"test_class_name": "CloneGraph",
34+
"test_helper_methods": [
35+
{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }
36+
],
37+
"test_methods": [
38+
{
39+
"name": "test_clone_graph",
40+
"parametrize": "adj_list",
41+
"parametrize_typed": "adj_list: list[list[int]]",
42+
"test_cases": "[[[2, 4], [1, 3], [2, 4], [1, 3]], [[]], []]",
43+
"body": "node = GraphNode.from_adjacency_list(adj_list)\nresult = self.solution.clone_graph(node)\nassert result.is_clone(node) if result else node is None"
44+
}
45+
],
46+
"playground_imports": "from solution import Solution\n\nfrom leetcode_py import GraphNode",
47+
"playground_test_case": "# Example test case\nadj_list = [[2,4],[1,3],[2,4],[1,3]]\nnode = GraphNode.from_adjacency_list(adj_list)",
48+
"playground_execution": "result = Solution().clone_graph(node)\nresult",
49+
"playground_assertion": "assert result.is_clone(node) if result else node is None"
50+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"problem_name": "evaluate_reverse_polish_notation",
3+
"solution_class_name": "Solution",
4+
"problem_number": "150",
5+
"problem_title": "Evaluate Reverse Polish Notation",
6+
"difficulty": "Medium",
7+
"topics": "Array, Math, Stack",
8+
"tags": ["grind-75"],
9+
"readme_description": "You are given an array of strings `tokens` that represents an arithmetic expression in a **Reverse Polish Notation**.\n\nEvaluate the expression. Return *an integer that represents the value of the expression*.\n\n**Note that:**\n\n- The valid operators are `'+'`, `'-'`, `'*'`, and `'/'`.\n- Each operand may be an integer or another expression.\n- The division between two integers always **truncates toward zero**.\n- There will not be any division by zero.\n- The input represents a valid arithmetic expression in a reverse polish notation.\n- The answer and all the intermediate calculations can be represented in a **32-bit** integer.",
10+
"readme_examples": [
11+
{
12+
"content": "```\nInput: tokens = [\"2\",\"1\",\"+\",\"3\",\"*\"]\nOutput: 9\n```\n**Explanation:** ((2 + 1) * 3) = 9"
13+
},
14+
{
15+
"content": "```\nInput: tokens = [\"4\",\"13\",\"5\",\"/\",\"+\"]\nOutput: 6\n```\n**Explanation:** (4 + (13 / 5)) = 6"
16+
},
17+
{
18+
"content": "```\nInput: tokens = [\"10\",\"6\",\"9\",\"3\",\"+\",\"-11\",\"*\",\"/\",\"*\",\"17\",\"+\",\"5\",\"+\"]\nOutput: 22\n```\n**Explanation:** ((10 * (6 / ((9 + 3) * -11))) + 17) + 5 = 22"
19+
}
20+
],
21+
"readme_constraints": "- `1 <= tokens.length <= 10^4`\n- `tokens[i]` is either an operator: `\"+\"`, `\"-\"`, `\"*\"`, or `\"/\"`, or an integer in the range `[-200, 200]`.",
22+
"readme_additional": "",
23+
"solution_imports": "",
24+
"solution_methods": [
25+
{
26+
"name": "eval_rpn",
27+
"parameters": "tokens: list[str]",
28+
"return_type": "int",
29+
"dummy_return": "0"
30+
}
31+
],
32+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .solution import Solution",
33+
"test_class_name": "EvaluateReversePolishNotation",
34+
"test_helper_methods": [
35+
{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }
36+
],
37+
"test_methods": [
38+
{
39+
"name": "test_eval_rpn",
40+
"parametrize": "tokens, expected",
41+
"parametrize_typed": "tokens: list[str], expected: int",
42+
"test_cases": "[([\"2\", \"1\", \"+\", \"3\", \"*\"], 9), ([\"4\", \"13\", \"5\", \"/\", \"+\"], 6), ([\"10\", \"6\", \"9\", \"3\", \"+\", \"-11\", \"*\", \"/\", \"*\", \"17\", \"+\", \"5\", \"+\"], 22)]",
43+
"body": "result = self.solution.eval_rpn(tokens)\nassert result == expected"
44+
}
45+
],
46+
"playground_imports": "from solution import Solution",
47+
"playground_test_case": "# Example test case\ntokens = [\\\"2\\\", \\\"1\\\", \\\"+\\\", \\\"3\\\", \\\"*\\\"]\nexpected = 9",
48+
"playground_execution": "result = Solution().eval_rpn(tokens)\nresult",
49+
"playground_assertion": "assert result == expected"
50+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"problem_name": "minimum_height_trees",
3+
"solution_class_name": "Solution",
4+
"problem_number": "310",
5+
"problem_title": "Minimum Height Trees",
6+
"difficulty": "Medium",
7+
"topics": "Depth-First Search, Breadth-First Search, Graph, Topological Sort",
8+
"tags": ["grind-75"],
9+
"readme_description": "A tree is an undirected graph in which any two vertices are connected by *exactly* one path. In other words, any connected graph without simple cycles is a tree.\n\nGiven a tree of `n` nodes labelled from `0` to `n - 1`, and an array of `n - 1` `edges` where `edges[i] = [ai, bi]` indicates that there is an undirected edge between the two nodes `ai` and `bi` in the tree, you can choose any node of the tree as the root. When you select a node `x` as the root, the result tree has height `h`. Among all possible rooted trees, those with minimum height (i.e. `min(h)`) are called **minimum height trees** (MHTs).\n\nReturn *a list of all **MHTs'** root labels*. You can return the answer in **any order**.\n\nThe **height** of a rooted tree is the number of edges on the longest downward path between the root and a leaf.",
10+
"readme_examples": [
11+
{
12+
"content": "<img alt=\"\" src=\"https://assets.leetcode.com/uploads/2020/09/01/e1.jpg\" style=\"width: 800px; height: 213px;\" />\n\n```\nInput: n = 4, edges = [[1,0],[1,2],[1,3]]\nOutput: [1]\nExplanation: As shown, the height of the tree is 1 when the root is the node with label 1 which is the only MHT.\n```"
13+
},
14+
{
15+
"content": "<img alt=\"\" src=\"https://assets.leetcode.com/uploads/2020/09/01/e2.jpg\" style=\"width: 800px; height: 321px;\" />\n\n```\nInput: n = 6, edges = [[3,0],[3,1],[3,2],[3,4],[5,4]]\nOutput: [3,4]\n```"
16+
}
17+
],
18+
"readme_constraints": "- `1 <= n <= 2 * 10^4`\n- `edges.length == n - 1`\n- `0 <= ai, bi < n`\n- `ai != bi`\n- All the pairs `(ai, bi)` are distinct.\n- The given input is **guaranteed** to be a tree and there will be **no repeated** edges.",
19+
"readme_additional": "",
20+
"solution_imports": "",
21+
"solution_methods": [
22+
{
23+
"name": "find_min_height_trees",
24+
"parameters": "n: int, edges: list[list[int]]",
25+
"return_type": "list[int]",
26+
"dummy_return": "[]"
27+
}
28+
],
29+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .solution import Solution",
30+
"test_class_name": "MinimumHeightTrees",
31+
"test_helper_methods": [
32+
{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }
33+
],
34+
"test_methods": [
35+
{
36+
"name": "test_find_min_height_trees",
37+
"parametrize": "n, edges, expected",
38+
"parametrize_typed": "n: int, edges: list[list[int]], expected: list[int]",
39+
"test_cases": "[(4, [[1,0],[1,2],[1,3]], [1]), (6, [[3,0],[3,1],[3,2],[3,4],[5,4]], [3,4]), (1, [], [0])]",
40+
"body": "result = self.solution.find_min_height_trees(n, edges)\nassert sorted(result) == sorted(expected)"
41+
}
42+
],
43+
"playground_imports": "from solution import Solution",
44+
"playground_test_case": "# Example test case\nn = 4\nedges = [[1,0],[1,2],[1,3]]\nexpected = [1]",
45+
"playground_execution": "result = Solution().find_min_height_trees(n, edges)\nresult",
46+
"playground_assertion": "assert sorted(result) == sorted(expected)"
47+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"problem_name": "task_scheduler",
3+
"solution_class_name": "Solution",
4+
"problem_number": "621",
5+
"problem_title": "Task Scheduler",
6+
"difficulty": "Medium",
7+
"topics": "Array, Hash Table, Greedy, Sorting, Heap (Priority Queue), Counting",
8+
"tags": ["grind-75"],
9+
"readme_description": "You are given an array of CPU `tasks`, each labeled with a letter from A to Z, and a number `n`. Each CPU interval can be idle or allow the completion of one task. Tasks can be completed in any order, but there's a constraint: there has to be a gap of **at least** `n` intervals between two tasks with the same label.\n\nReturn the **minimum** number of CPU intervals required to complete all tasks.",
10+
"readme_examples": [
11+
{
12+
"content": "```\nInput: tasks = [\"A\",\"A\",\"A\",\"B\",\"B\",\"B\"], n = 2\nOutput: 8\n```\n**Explanation:** A possible sequence is: A -> B -> idle -> A -> B -> idle -> A -> B.\n\nAfter completing task A, you must wait two intervals before doing A again. The same applies to task B. In the 3rd interval, neither A nor B can be done, so you idle. By the 4th interval, you can do A again as 2 intervals have passed."
13+
},
14+
{
15+
"content": "```\nInput: tasks = [\"A\",\"C\",\"A\",\"B\",\"D\",\"B\"], n = 1\nOutput: 6\n```\n**Explanation:** A possible sequence is: A -> B -> C -> D -> A -> B.\n\nWith a cooling interval of 1, you can repeat a task after just one other task."
16+
},
17+
{
18+
"content": "```\nInput: tasks = [\"A\",\"A\",\"A\", \"B\",\"B\",\"B\"], n = 3\nOutput: 10\n```\n**Explanation:** A possible sequence is: A -> B -> idle -> idle -> A -> B -> idle -> idle -> A -> B.\n\nThere are only two types of tasks, A and B, which need to be separated by 3 intervals. This leads to idling twice between repetitions of these tasks."
19+
}
20+
],
21+
"readme_constraints": "- `1 <= tasks.length <= 10^4`\n- `tasks[i]` is an uppercase English letter.\n- `0 <= n <= 100`",
22+
"readme_additional": "",
23+
"solution_imports": "",
24+
"solution_methods": [
25+
{
26+
"name": "least_interval",
27+
"parameters": "tasks: list[str], n: int",
28+
"return_type": "int",
29+
"dummy_return": "0"
30+
}
31+
],
32+
"test_imports": "import pytest\nfrom leetcode_py.test_utils import logged_test\nfrom .solution import Solution",
33+
"test_class_name": "TaskScheduler",
34+
"test_helper_methods": [
35+
{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }
36+
],
37+
"test_methods": [
38+
{
39+
"name": "test_least_interval",
40+
"parametrize": "tasks, n, expected",
41+
"parametrize_typed": "tasks: list[str], n: int, expected: int",
42+
"test_cases": "[([\"A\", \"A\", \"A\", \"B\", \"B\", \"B\"], 2, 8), ([\"A\", \"C\", \"A\", \"B\", \"D\", \"B\"], 1, 6), ([\"A\", \"A\", \"A\", \"B\", \"B\", \"B\"], 3, 10)]",
43+
"body": "result = self.solution.least_interval(tasks, n)\nassert result == expected"
44+
}
45+
],
46+
"playground_imports": "from solution import Solution",
47+
"playground_test_case": "# Example test case\ntasks = [\\\"A\\\", \\\"A\\\", \\\"A\\\", \\\"B\\\", \\\"B\\\", \\\"B\\\"]\nn = 2\nexpected = 8",
48+
"playground_execution": "result = Solution().least_interval(tasks, n)\nresult",
49+
"playground_assertion": "assert result == expected"
50+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"problem_name": "validate_binary_search_tree",
3+
"solution_class_name": "Solution",
4+
"problem_number": "98",
5+
"problem_title": "Validate Binary Search Tree",
6+
"difficulty": "Medium",
7+
"topics": "Tree, Depth-First Search, Binary Search Tree, Binary Tree",
8+
"tags": ["grind-75"],
9+
"readme_description": "Given the `root` of a binary tree, determine if it is a valid binary search tree (BST).\n\nA **valid BST** is defined as follows:\n\n- The left subtree of a node contains only nodes with keys **strictly less than** the node's key.\n- The right subtree of a node contains only nodes with keys **strictly greater than** the node's key.\n- Both the left and right subtrees must also be binary search trees.",
10+
"readme_examples": [
11+
{
12+
"content": "![Example 1](https://assets.leetcode.com/uploads/2020/12/01/tree1.jpg)\n\n```\nInput: root = [2,1,3]\nOutput: true\n```"
13+
},
14+
{
15+
"content": "![Example 2](https://assets.leetcode.com/uploads/2020/12/01/tree2.jpg)\n\n```\nInput: root = [5,1,4,null,null,3,6]\nOutput: false\n```\n**Explanation:** The root node's value is 5 but its right child's value is 4."
16+
}
17+
],
18+
"readme_constraints": "- The number of nodes in the tree is in the range `[1, 10^4]`.\n- `-2^31 <= Node.val <= 2^31 - 1`",
19+
"readme_additional": "",
20+
"solution_imports": "from leetcode_py import TreeNode",
21+
"solution_methods": [
22+
{
23+
"name": "is_valid_bst",
24+
"parameters": "root: TreeNode[int] | None",
25+
"return_type": "bool",
26+
"dummy_return": "False"
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": "ValidateBinarySearchTree",
31+
"test_helper_methods": [
32+
{ "name": "setup_method", "parameters": "", "body": "self.solution = Solution()" }
33+
],
34+
"test_methods": [
35+
{
36+
"name": "test_is_valid_bst",
37+
"parametrize": "root_list, expected",
38+
"parametrize_typed": "root_list: list[int | None], expected: bool",
39+
"test_cases": "[([2, 1, 3], True), ([5, 1, 4, None, None, 3, 6], False), ([2, 1, 3], True), ([1], True), ([1, 1], False)]",
40+
"body": "root = TreeNode.from_list(root_list)\nresult = self.solution.is_valid_bst(root)\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: list[int | None] = [2, 1, 3]\nexpected = True",
45+
"playground_execution": "root = TreeNode.from_list(root_list)\nresult = Solution().is_valid_bst(root)\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 ?= invert_binary_tree
2+
PROBLEM ?= task_scheduler
33
FORCE ?= 0
44

55
sync_submodules:

0 commit comments

Comments
 (0)