C++实现LeetCode(133.克隆无向图)

 更新时间:2021年07月28日 14:29:13   作者:Grandyang  
这篇文章主要介绍了C++实现LeetCode(133.克隆无向图),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

[LeetCode] 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 val (int) and a list (List[Node]) of its neighbors.

Example:

Input:
{"$id":"1","neighbors":[{"$id":"2","neighbors":[{"$ref":"1"},{"$id":"3","neighbors":[{"$ref":"2"},{"$id":"4","neighbors":[{"$ref":"3"},{"$ref":"1"}],"val":4}],"val":3}],"val":2},{"$ref":"4"}],"val":1}

Explanation:
Node 1's value is 1, and it has two neighbors: Node 2 and 4.
Node 2's value is 2, and it has two neighbors: Node 1 and 3.
Node 3's value is 3, and it has two neighbors: Node 2 and 4.
Node 4's value is 4, and it has two neighbors: Node 1 and 3.

Note:

  1. The number of nodes will be between 1 and 100.
  2. The undirected graph is a simple graph, which means no repeated edges and no self-loops in the graph.
  3. Since the graph is undirected, if node p has node q as neighbor, then node q must have node p as neighbor too.
  4. You must return the copy of the given node as a reference to the cloned graph.

这道无向图的复制问题和之前的 Copy List with Random Pointer 有些类似,那道题的难点是如何处理每个结点的随机指针,这道题目的难点在于如何处理每个结点的 neighbors,由于在深度拷贝每一个结点后,还要将其所有 neighbors 放到一个 vector 中,而如何避免重复拷贝呢?这道题好就好在所有结点值不同,所以我们可以使用 HashMap 来对应原图中的结点和新生成的克隆图中的结点。对于图的遍历的两大基本方法是深度优先搜索 DFS 和广度优先搜索 BFS,这里我们先使用深度优先搜索DFS来解答此题,在递归函数中,首先判空,然后再看当前的结点是否已经被克隆过了,若在 HashMap 中存在,则直接返回其映射结点。否则就克隆当前结点,并在 HashMap 中建立映射,然后遍历当前结点的所有 neihbor 结点,调用递归函数并且加到克隆结点的 neighbors 数组中即可,代码如下:

解法一:

class Solution {
public:
    Node* cloneGraph(Node* node) {
        unordered_map<Node*, Node*> m;
        return helper(node, m);
    }
    Node* helper(Node* node, unordered_map<Node*, Node*>& m) {
        if (!node) return NULL;
        if (m.count(node)) return m[node];
        Node *clone = new Node(node->val);
        m[node] = clone;
        for (Node *neighbor : node->neighbors) {
            clone->neighbors.push_back(helper(neighbor, m));
        }
        return clone;
    }
};

我们也可以使用 BFS 来遍历图,使用队列 queue 进行辅助,还是需要一个 HashMap 来建立原图结点和克隆结点之间的映射。先克隆当前结点,然后建立映射,并加入 queue 中,进行 while 循环。在循环中,取出队首结点,遍历其所有 neighbor 结点,若不在 HashMap 中,我们根据 neigbor 结点值克隆一个新 neighbor 结点,建立映射,并且排入 queue 中。然后将 neighbor 结点在 HashMap 中的映射结点加入到克隆结点的 neighbors 数组中即可,参见代码如下:

解法二:

class Solution {
public:
    Node* cloneGraph(Node* node) {
        if (!node) return NULL;
        unordered_map<Node*, Node*> m;
        queue<Node*> q{{node}};
        Node *clone = new Node(node->val);
        m[node] = clone;
        while (!q.empty()) {
            Node *t = q.front(); q.pop();
            for (Node *neighbor : t->neighbors) {
                if (!m.count(neighbor)) {
                    m[neighbor] = new Node(neighbor->val);
                    q.push(neighbor);
                }
                m[t]->neighbors.push_back(m[neighbor]);
            }
        }
        return clone;
    }
};

类似题目:

Copy List with Random Pointer

参考资料:

https://leetcode.com/problems/clone-graph/

https://leetcode.com/problems/clone-graph/discuss/42313/C%2B%2B-BFSDFS

https://leetcode.com/problems/clone-graph/discuss/42309/Depth-First-Simple-Java-Solution

到此这篇关于C++实现LeetCode(133.克隆无向图)的文章就介绍到这了,更多相关C++实现克隆无向图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 利用rapidjson实现解析嵌套的json的方法示例

    利用rapidjson实现解析嵌套的json的方法示例

    今天小编就为大家分享一篇关于利用rapidjson实现解析嵌套的json的方法示例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04
  • C++堆排序算法实例详解

    C++堆排序算法实例详解

    这篇文章主要介绍了C++堆排序算法,简单分析了堆排序算法的原理并结合实例形式分析了C++实现堆排序的具体操作技巧,需要的朋友可以参考下
    2017-08-08
  • C语言趣味编程之水仙花数

    C语言趣味编程之水仙花数

    这篇文章介绍了C语言趣味编程之水仙花数,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-11-11
  • 使用dc画笔画矩形、直线与椭圆示例

    使用dc画笔画矩形、直线与椭圆示例

    这篇文章主要介绍了使用dc画笔画矩形、直线与椭圆示例,需要的朋友可以参考下
    2014-04-04
  • C语言与C++中关于字符串使用的比较

    C语言与C++中关于字符串使用的比较

    字符串是我们再熟悉不过的东西了,任何语言中字符串都是基础都要经常用到,那么在不同语言中字符串的用法一样吗?下面我们来看看C语言与C++中字符串使用的比较
    2022-05-05
  • 基于C语言实现钻石棋游戏的示例代码

    基于C语言实现钻石棋游戏的示例代码

    独立钻石是源于18世纪法国的宫廷贵族的自我挑战类单人棋游戏,可以锻炼逻辑思维能力。本文将用C语言实现这一简单的游戏,感兴趣的小伙伴可以了解一下
    2023-02-02
  • 常用排序算法的C语言版实现示例整理

    常用排序算法的C语言版实现示例整理

    这篇文章主要介绍了常用排序算法的C语言版实现示例整理,包括快速排序及冒泡排序等,基本上都给出了时间复杂度,需要的朋友可以参考下
    2016-03-03
  • 深入理解C++之策略模式

    深入理解C++之策略模式

    下面小编就为大家带来一篇深入理解C++之策略模式。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • C++模拟实现vector示例代码图文讲解

    C++模拟实现vector示例代码图文讲解

    这篇文章主要介绍了C++容器Vector的模拟实现,Vector是一个能够存放任意类型的动态数组,有点类似数组,是一个连续地址空间,下文更多详细内容的介绍,需要的小伙伴可以参考一下
    2023-02-02
  • 一篇文章带你了解C++语法基础--字符串

    一篇文章带你了解C++语法基础--字符串

    这篇文章主要介绍了C++常用字符串分割方法实例汇总,包括了strtok函数、STL、Boost等常用的各类字符串分割方法,非常具有实用价值,需要的朋友可以参考下
    2021-08-08

最新评论