⭐算法OJ⭐克隆图【BFS】(C++实现)Clone Graph
前情提要:图论入门【数据结构基础】:什么是图?如何表示图?
133. 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.
class Node {
public int val;
public List<Node> neighbors;
}
Test case format:
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.
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.
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.
Example 1:
Input: adjList = [[2,4],[1,3],[2,4],[1,3]]
Output: [[2,4],[1,3],[2,4],[1,3]]
Explanation: There are 4 nodes in the graph.
1st node (val = 1)'s neighbors are 2nd node (val = 2) and 4th node (val = 4).
2nd node (val = 2)'s neighbors are 1st node (val = 1) and 3rd node (val = 3).
3rd node (val = 3)'s neighbors are 2nd node (val = 2) and 4th node (val = 4).
4th node (val = 4)'s neighbors are 1st node (val = 1) and 3rd node (val = 3).
Example 2:
Input: adjList = [[]]
Output: [[]]
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.
Example 3:
Input: adjList = []
Output: []
Explanation: This an empty graph, it does not have any nodes.
要克隆一个无向连通图,我们可以使用深度优先搜索(DFS) 或广度优先搜索(BFS) 来遍历图,并在遍历过程中创建每个节点的副本。为了确保每个节点只被复制一次,我们可以使用一个哈希表(或字典)来存储已经复制过的节点。
代码设计
Node
类: 定义了图节点的结构,包含一个整数值val
和一个邻居节点列表neighbors
。cloneGraph
函数:- 首先检查输入节点是否为空,如果为空则返回
nullptr
。 - 使用一个哈希表
visited
来存储原节点和克隆节点的映射。 - 使用队列
q
来进行BFS遍历。 - 克隆第一个节点并将其加入哈希表。
- 在BFS过程中,遍历每个节点的邻居,如果邻居节点还没有被克隆,则克隆它并加入哈希表和队列。
- 最后,返回克隆图的第一个节点。
- 首先检查输入节点是否为空,如果为空则返回
代码实现
#include <unordered_map>
#include <queue>
#include <vector>
using namespace std;
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> neighbors;
Node() {
val = 0;
neighbors = vector<Node*>();
}
Node(int _val) {
val = _val;
neighbors = vector<Node*>();
}
Node(int _val, vector<Node*> _neighbors) {
val = _val;
neighbors = _neighbors;
}
};
class Solution {
public:
Node* cloneGraph(Node* node) {
if (!node) return nullptr;
// 创建一个哈希表来存储原节点和克隆节点的映射
unordered_map<Node*, Node*> visited;
// 创建一个队列用于BFS
queue<Node*> q;
q.push(node);
// 克隆第一个节点
visited[node] = new Node(node->val);
// 开始BFS
while (!q.empty()) {
Node* current = q.front();
q.pop();
// 遍历当前节点的邻居
for (Node* neighbor : current->neighbors) {
// 如果邻居节点还没有被克隆
if (visited.find(neighbor) == visited.end()) {
// 克隆邻居节点并加入哈希表
visited[neighbor] = new Node(neighbor->val);
// 将邻居节点加入队列
q.push(neighbor);
}
// 将克隆的邻居节点加入当前克隆节点的邻居列表
visited[current]->neighbors.push_back(visited[neighbor]);
}
}
// 返回克隆图的第一个节点
return visited[node];
}
};
复杂度
- 时间复杂度:每个节点和每条边都会被访问一次,因此时间复杂度为 O ( N + E ) O(N + E) O(N+E),其中 N N N是节点数, E E E是边数。
- 空间复杂度:使用了哈希表来存储节点映射,空间复杂度为 O ( N ) O(N) O(N)。