Skip to content

Commit b8343b2

Browse files
committed
feat: add more questions
1 parent f164898 commit b8343b2

File tree

10 files changed

+758
-2
lines changed

10 files changed

+758
-2
lines changed
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, expected_adj_list",
41+
"parametrize_typed": "adj_list: list[list[int]], expected_adj_list: list[list[int]]",
42+
"test_cases": "[([[2,4],[1,3],[2,4],[1,3]], [[2,4],[1,3],[2,4],[1,3]]), ([[]], [[]]), ([], [])]",
43+
"body": "node = GraphNode.from_adjacency_list(adj_list)\nexpected = GraphNode.from_adjacency_list(expected_adj_list)\nresult = self.solution.clone_graph(node)\nassert GraphNode.to_adjacency_list(result) == GraphNode.to_adjacency_list(expected)"
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)\nexpected_adj_list = [[2,4],[1,3],[2,4],[1,3]]",
48+
"playground_execution": "result = Solution().clone_graph(node)\nGraphNode.to_adjacency_list(result)",
49+
"playground_assertion": "assert GraphNode.to_adjacency_list(result) == expected_adj_list"
50+
}

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 ?= clone_graph
33
FORCE ?= 0
44

55
sync_submodules:

leetcode/clone_graph/README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Clone Graph
2+
3+
**Difficulty:** Medium
4+
**Topics:** Hash Table, Depth-First Search, Breadth-First Search, Graph
5+
**Tags:** grind-75
6+
7+
**LeetCode:** [Problem 133](https://leetcode.com/problems/clone-graph/description/)
8+
9+
## Problem Description
10+
11+
Given a reference of a node in a **connected** undirected graph.
12+
13+
Return a **deep copy** (clone) of the graph.
14+
15+
Each node in the graph contains a value (`int`) and a list (`List[Node]`) of its neighbors.
16+
17+
```
18+
class Node {
19+
public int val;
20+
public List<Node> neighbors;
21+
}
22+
```
23+
24+
**Test case format:**
25+
26+
For 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.
27+
28+
**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.
29+
30+
The 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.
31+
32+
## Examples
33+
34+
### Example 1:
35+
36+
<img alt="" src="https://assets.leetcode.com/uploads/2019/11/04/133_clone_graph_question.png" style="width: 454px; height: 500px;" />
37+
38+
```
39+
Input: adjList = [[2,4],[1,3],[2,4],[1,3]]
40+
Output: [[2,4],[1,3],[2,4],[1,3]]
41+
Explanation: There are 4 nodes in the graph.
42+
1st node (val = 1)'s neighbors are 2nd node (val = 2) and 4th node (val = 4).
43+
2nd node (val = 2)'s neighbors are 1st node (val = 1) and 3rd node (val = 3).
44+
3rd node (val = 3)'s neighbors are 2nd node (val = 2) and 4th node (val = 4).
45+
4th node (val = 4)'s neighbors are 1st node (val = 1) and 3rd node (val = 3).
46+
```
47+
48+
### Example 2:
49+
50+
<img alt="" src="https://assets.leetcode.com/uploads/2020/01/07/graph.png" style="width: 163px; height: 148px;" />
51+
52+
```
53+
Input: adjList = [[]]
54+
Output: [[]]
55+
Explanation: 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.
56+
```
57+
58+
### Example 3:
59+
60+
```
61+
Input: adjList = []
62+
Output: []
63+
Explanation: This an empty graph, it does not have any nodes.
64+
```
65+
66+
## Constraints
67+
68+
- The number of nodes in the graph is in the range `[0, 100]`.
69+
- `1 <= Node.val <= 100`
70+
- `Node.val` is unique for each node.
71+
- There are no repeated edges and no self-loops in the graph.
72+
- The Graph is connected and all nodes can be visited starting from the given node.

leetcode/clone_graph/__init__.py

Whitespace-only changes.
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
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 GraphNode"
13+
]
14+
},
15+
{
16+
"cell_type": "code",
17+
"execution_count": 2,
18+
"id": "setup",
19+
"metadata": {},
20+
"outputs": [
21+
{
22+
"data": {
23+
"text/html": [
24+
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
25+
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
26+
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
27+
"<!-- Generated by graphviz version 13.1.2 (20250808.2320)\n",
28+
" -->\n",
29+
"<!-- Pages: 1 -->\n",
30+
"<svg width=\"135pt\" height=\"138pt\"\n",
31+
" viewBox=\"0.00 0.00 135.00 138.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
32+
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 134.25)\">\n",
33+
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-134.25 131.36,-134.25 131.36,4 -4,4\"/>\n",
34+
"<!-- 1 -->\n",
35+
"<g id=\"node1\" class=\"node\">\n",
36+
"<title>1</title>\n",
37+
"<ellipse fill=\"lightblue\" stroke=\"black\" cx=\"18\" cy=\"-53.59\" rx=\"18\" ry=\"18\"/>\n",
38+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"18\" y=\"-48.54\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
39+
"</g>\n",
40+
"<!-- 2 -->\n",
41+
"<g id=\"node2\" class=\"node\">\n",
42+
"<title>2</title>\n",
43+
"<ellipse fill=\"lightblue\" stroke=\"black\" cx=\"109.36\" cy=\"-76.24\" rx=\"18\" ry=\"18\"/>\n",
44+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"109.36\" y=\"-71.19\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n",
45+
"</g>\n",
46+
"<!-- 1&#45;&#45;2 -->\n",
47+
"<g id=\"edge1\" class=\"edge\">\n",
48+
"<title>1&#45;&#45;2</title>\n",
49+
"<path fill=\"none\" stroke=\"gray\" d=\"M35.61,-57.96C51.69,-61.94 75.33,-67.81 91.48,-71.81\"/>\n",
50+
"</g>\n",
51+
"<!-- 4 -->\n",
52+
"<g id=\"node3\" class=\"node\">\n",
53+
"<title>4</title>\n",
54+
"<ellipse fill=\"lightblue\" stroke=\"black\" cx=\"64.17\" cy=\"-18\" rx=\"18\" ry=\"18\"/>\n",
55+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"64.17\" y=\"-12.95\" font-family=\"Times,serif\" font-size=\"14.00\">4</text>\n",
56+
"</g>\n",
57+
"<!-- 1&#45;&#45;4 -->\n",
58+
"<g id=\"edge2\" class=\"edge\">\n",
59+
"<title>1&#45;&#45;4</title>\n",
60+
"<path fill=\"none\" stroke=\"gray\" d=\"M32.61,-42.33C38.1,-38.09 44.34,-33.28 49.81,-29.07\"/>\n",
61+
"</g>\n",
62+
"<!-- 3 -->\n",
63+
"<g id=\"node4\" class=\"node\">\n",
64+
"<title>3</title>\n",
65+
"<ellipse fill=\"lightblue\" stroke=\"black\" cx=\"63.48\" cy=\"-112.25\" rx=\"18\" ry=\"18\"/>\n",
66+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"63.48\" y=\"-107.2\" font-family=\"Times,serif\" font-size=\"14.00\">3</text>\n",
67+
"</g>\n",
68+
"<!-- 2&#45;&#45;3 -->\n",
69+
"<g id=\"edge3\" class=\"edge\">\n",
70+
"<title>2&#45;&#45;3</title>\n",
71+
"<path fill=\"none\" stroke=\"gray\" d=\"M94.84,-87.64C89.38,-91.92 83.18,-96.79 77.74,-101.05\"/>\n",
72+
"</g>\n",
73+
"<!-- 3&#45;&#45;4 -->\n",
74+
"<g id=\"edge4\" class=\"edge\">\n",
75+
"<title>3&#45;&#45;4</title>\n",
76+
"<path fill=\"none\" stroke=\"gray\" d=\"M63.61,-94.08C63.73,-77.49 63.91,-53.1 64.03,-36.44\"/>\n",
77+
"</g>\n",
78+
"</g>\n",
79+
"</svg>\n"
80+
],
81+
"text/plain": [
82+
"GraphNode({1: [2, 4], 2: [1, 3], 3: [2, 4], 4: [1, 3]})"
83+
]
84+
},
85+
"execution_count": 2,
86+
"metadata": {},
87+
"output_type": "execute_result"
88+
}
89+
],
90+
"source": [
91+
"# Example test case\n",
92+
"adj_list = [[2, 4], [1, 3], [2, 4], [1, 3]]\n",
93+
"node = GraphNode.from_adjacency_list(adj_list)\n",
94+
"node"
95+
]
96+
},
97+
{
98+
"cell_type": "code",
99+
"execution_count": 3,
100+
"id": "execute",
101+
"metadata": {},
102+
"outputs": [
103+
{
104+
"data": {
105+
"text/html": [
106+
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
107+
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
108+
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
109+
"<!-- Generated by graphviz version 13.1.2 (20250808.2320)\n",
110+
" -->\n",
111+
"<!-- Pages: 1 -->\n",
112+
"<svg width=\"135pt\" height=\"138pt\"\n",
113+
" viewBox=\"0.00 0.00 135.00 138.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
114+
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 134.25)\">\n",
115+
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-134.25 131.36,-134.25 131.36,4 -4,4\"/>\n",
116+
"<!-- 1 -->\n",
117+
"<g id=\"node1\" class=\"node\">\n",
118+
"<title>1</title>\n",
119+
"<ellipse fill=\"lightblue\" stroke=\"black\" cx=\"18\" cy=\"-53.59\" rx=\"18\" ry=\"18\"/>\n",
120+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"18\" y=\"-48.54\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
121+
"</g>\n",
122+
"<!-- 2 -->\n",
123+
"<g id=\"node2\" class=\"node\">\n",
124+
"<title>2</title>\n",
125+
"<ellipse fill=\"lightblue\" stroke=\"black\" cx=\"109.36\" cy=\"-76.24\" rx=\"18\" ry=\"18\"/>\n",
126+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"109.36\" y=\"-71.19\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n",
127+
"</g>\n",
128+
"<!-- 1&#45;&#45;2 -->\n",
129+
"<g id=\"edge1\" class=\"edge\">\n",
130+
"<title>1&#45;&#45;2</title>\n",
131+
"<path fill=\"none\" stroke=\"gray\" d=\"M35.61,-57.96C51.69,-61.94 75.33,-67.81 91.48,-71.81\"/>\n",
132+
"</g>\n",
133+
"<!-- 4 -->\n",
134+
"<g id=\"node3\" class=\"node\">\n",
135+
"<title>4</title>\n",
136+
"<ellipse fill=\"lightblue\" stroke=\"black\" cx=\"64.17\" cy=\"-18\" rx=\"18\" ry=\"18\"/>\n",
137+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"64.17\" y=\"-12.95\" font-family=\"Times,serif\" font-size=\"14.00\">4</text>\n",
138+
"</g>\n",
139+
"<!-- 1&#45;&#45;4 -->\n",
140+
"<g id=\"edge2\" class=\"edge\">\n",
141+
"<title>1&#45;&#45;4</title>\n",
142+
"<path fill=\"none\" stroke=\"gray\" d=\"M32.61,-42.33C38.1,-38.09 44.34,-33.28 49.81,-29.07\"/>\n",
143+
"</g>\n",
144+
"<!-- 3 -->\n",
145+
"<g id=\"node4\" class=\"node\">\n",
146+
"<title>3</title>\n",
147+
"<ellipse fill=\"lightblue\" stroke=\"black\" cx=\"63.48\" cy=\"-112.25\" rx=\"18\" ry=\"18\"/>\n",
148+
"<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"63.48\" y=\"-107.2\" font-family=\"Times,serif\" font-size=\"14.00\">3</text>\n",
149+
"</g>\n",
150+
"<!-- 2&#45;&#45;3 -->\n",
151+
"<g id=\"edge3\" class=\"edge\">\n",
152+
"<title>2&#45;&#45;3</title>\n",
153+
"<path fill=\"none\" stroke=\"gray\" d=\"M94.84,-87.64C89.38,-91.92 83.18,-96.79 77.74,-101.05\"/>\n",
154+
"</g>\n",
155+
"<!-- 3&#45;&#45;4 -->\n",
156+
"<g id=\"edge4\" class=\"edge\">\n",
157+
"<title>3&#45;&#45;4</title>\n",
158+
"<path fill=\"none\" stroke=\"gray\" d=\"M63.61,-94.08C63.73,-77.49 63.91,-53.1 64.03,-36.44\"/>\n",
159+
"</g>\n",
160+
"</g>\n",
161+
"</svg>\n"
162+
],
163+
"text/plain": [
164+
"GraphNode({1: [2, 4], 2: [1, 3], 3: [2, 4], 4: [1, 3]})"
165+
]
166+
},
167+
"execution_count": 3,
168+
"metadata": {},
169+
"output_type": "execute_result"
170+
}
171+
],
172+
"source": [
173+
"result = Solution().clone_graph(node)\n",
174+
"result"
175+
]
176+
},
177+
{
178+
"cell_type": "code",
179+
"execution_count": 4,
180+
"id": "test",
181+
"metadata": {},
182+
"outputs": [],
183+
"source": [
184+
"if result is None:\n",
185+
" assert node is None\n",
186+
"else:\n",
187+
" assert result.is_clone(node)"
188+
]
189+
}
190+
],
191+
"metadata": {
192+
"kernelspec": {
193+
"display_name": "leetcode-py-py3.13",
194+
"language": "python",
195+
"name": "python3"
196+
},
197+
"language_info": {
198+
"codemirror_mode": {
199+
"name": "ipython",
200+
"version": 3
201+
},
202+
"file_extension": ".py",
203+
"mimetype": "text/x-python",
204+
"name": "python",
205+
"nbconvert_exporter": "python",
206+
"pygments_lexer": "ipython3",
207+
"version": "3.13.7"
208+
}
209+
},
210+
"nbformat": 4,
211+
"nbformat_minor": 5
212+
}

0 commit comments

Comments
 (0)