mirror of
https://hub.njuu.cf/TheAlgorithms/Python.git
synced 2023-10-11 13:06:12 +08:00
Added algorithm to deeply clone a graph (#9765)
* Added algorithm to deeply clone a graph * Fixed file name and removed a function call * Removed nested function and fixed class parameter types * Fixed doctests * bug fix * Added class decorator * Updated doctests and fixed precommit errors * Cleaned up code * Simplified doctest * Added doctests * Code simplification
This commit is contained in:
parent
b316a96128
commit
cd684fd947
77
graphs/deep_clone_graph.py
Normal file
77
graphs/deep_clone_graph.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
"""
|
||||||
|
LeetCode 133. Clone Graph
|
||||||
|
https://leetcode.com/problems/clone-graph/
|
||||||
|
|
||||||
|
Given a reference of a node in a connected undirected graph.
|
||||||
|
|
||||||
|
Return a deep copy (clone) of the graph.
|
||||||
|
|
||||||
|
Each node in the graph contains a value (int) and a list (List[Node]) of its
|
||||||
|
neighbors.
|
||||||
|
"""
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Node:
|
||||||
|
value: int = 0
|
||||||
|
neighbors: list["Node"] | None = None
|
||||||
|
|
||||||
|
def __post_init__(self) -> None:
|
||||||
|
"""
|
||||||
|
>>> Node(3).neighbors
|
||||||
|
[]
|
||||||
|
"""
|
||||||
|
self.neighbors = self.neighbors or []
|
||||||
|
|
||||||
|
def __hash__(self) -> int:
|
||||||
|
"""
|
||||||
|
>>> hash(Node(3)) != 0
|
||||||
|
True
|
||||||
|
"""
|
||||||
|
return id(self)
|
||||||
|
|
||||||
|
|
||||||
|
def clone_graph(node: Node | None) -> Node | None:
|
||||||
|
"""
|
||||||
|
This function returns a clone of a connected undirected graph.
|
||||||
|
>>> clone_graph(Node(1))
|
||||||
|
Node(value=1, neighbors=[])
|
||||||
|
>>> clone_graph(Node(1, [Node(2)]))
|
||||||
|
Node(value=1, neighbors=[Node(value=2, neighbors=[])])
|
||||||
|
>>> clone_graph(None) is None
|
||||||
|
True
|
||||||
|
"""
|
||||||
|
if not node:
|
||||||
|
return None
|
||||||
|
|
||||||
|
originals_to_clones = {} # map nodes to clones
|
||||||
|
|
||||||
|
stack = [node]
|
||||||
|
|
||||||
|
while stack:
|
||||||
|
original = stack.pop()
|
||||||
|
|
||||||
|
if original in originals_to_clones:
|
||||||
|
continue
|
||||||
|
|
||||||
|
originals_to_clones[original] = Node(original.value)
|
||||||
|
|
||||||
|
stack.extend(original.neighbors or [])
|
||||||
|
|
||||||
|
for original, clone in originals_to_clones.items():
|
||||||
|
for neighbor in original.neighbors or []:
|
||||||
|
cloned_neighbor = originals_to_clones[neighbor]
|
||||||
|
|
||||||
|
if not clone.neighbors:
|
||||||
|
clone.neighbors = []
|
||||||
|
|
||||||
|
clone.neighbors.append(cloned_neighbor)
|
||||||
|
|
||||||
|
return originals_to_clones[node]
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import doctest
|
||||||
|
|
||||||
|
doctest.testmod()
|
Loading…
Reference in New Issue
Block a user