# 26. Clone Graph

Given a reference of a node in a [**connected**](https://en.wikipedia.org/wiki/Connectivity_\(graph_theory\)#Connected_graph) undirected graph.

Return a [**deep copy**](https://en.wikipedia.org/wiki/Object_copying#Deep_copy) (clone) of the graph.

Each node in the graph contains a val (`int`) and a list (`List[Node]`) of its neighbors.

```
class Node {
    public int val;
    public List<Node> neighbors;
}
```

**Test case format:**

For simplicity sake, 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.

**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:**

![](https://assets.leetcode.com/uploads/2019/11/04/133_clone_graph_question.png)

```
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:**![](https://assets.leetcode.com/uploads/2020/01/07/graph.png)

```
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.
```

**Example 4:**![](https://assets.leetcode.com/uploads/2020/01/07/graph-1.png)

```
Input: adjList = [[2],[1]]
Output: [[2],[1]]
```

## Approach

We traverse the original graph and whenever we find a new unvisited node we create a new one and make its copy else we append its address in adjacency list.

## Solution: (DFS)

```cpp
/
// Definition for a Node.
class Node {
public:
    int val;
    vetor<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 *dfs(Node *&node, Node *&temp, vector<Node *> &s)
    {
        s[temp->val] = temp;

        for (int i = 0; i < node->neighbors.size(); i++)
        {
            if (s[node->neighbors[i]->val] == NULL)
            {
                Node *t1 = new Node;
                t1->val = node->neighbors[i]->val;
                temp->neighbors.push_back(t1);
                dfs(node->neighbors[i], t1, s);
            }
            else
            {
                temp->neighbors.push_back(s[node->neighbors[i]->val]);
            }
        }

        return temp;
    }

    Node *cloneGraph(Node *node)
    {
        
        if(node == NULL){
            return node;
        }
        
        vector<Node *> s(100 + 1, NULL);

        Node *temp = new Node;
        temp->val = node->val;
        s[temp->val] = temp;

        for (int i = 0; i < node->neighbors.size(); i++)
        {
            if (s[node->neighbors[i]->val] == NULL)
            {
                Node *t1 = new Node;
                t1->val = node->neighbors[i]->val;
                temp->neighbors.push_back(t1);
                dfs(node->neighbors[i], t1, s);
            }
            else
            {
                temp->neighbors.push_back(s[node->neighbors[i]->val]);
            }
        }

        return temp;
    }
};
```

## Solution: (BFS)

```cpp

// 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:
    void bfs(queue<pair<Node *, Node *>> &q, vector<Node *> &v)
    {

        while (!q.empty())
        {
            Node *node = q.front().first;
            Node *temp = q.front().second;
            q.pop();

            for (int i = 0; i < node->neighbors.size(); i++)
            {
                if (v[node->neighbors[i]->val] == NULL)
                {
                    Node *t1 = new Node;
                    t1->val = node->neighbors[i]->val;
                    q.push({node->neighbors[i], t1});
                    v[t1->val] = t1;
                    temp->neighbors.push_back(t1);
                }
                else
                {
                    temp->neighbors.push_back(v[node->neighbors[i]->val]);
                }
            }
        }
        return;
    }

    Node *cloneGraph(Node *node)
    {
        if(node == NULL){
            return node;
        }
        
        queue<pair<Node *, Node *>> q;
        vector<Node *> v(100 + 1, NULL);
        Node *temp = new Node;
        temp->val = node->val;
        v[temp->val] = temp;

        for (int i = 0; i < node->neighbors.size(); i++)
        {
            if (v[node->neighbors[i]->val] == NULL)
            {
                Node *t1 = new Node;
                t1->val = node->neighbors[i]->val;
                q.push({node->neighbors[i], t1});
                v[t1->val] = t1;
                temp->neighbors.push_back(t1);
            }
            else
            {
                temp->neighbors.push_back(v[node->neighbors[i]->val]);
            }
        }
        bfs(q, v);
        return temp;
    }
};
```

