设为首页 加入收藏

TOP

[C++]LeetCode: 129 Clone Graph (图的深拷贝 BFS && DFS)(二)
2015-07-20 17:23:18 来源: 作者: 【 】 浏览:5
Tags:LeetCode: 129 Clone Graph 拷贝 BFS & DFS
达式等价)


思路:题目的要求是让我们实现一个图的深拷贝。深拷贝指的是复制另外一个对象到自己的对象中,且两者不共享一个内存区,浅拷贝指的是两者共享一个内存区。所以我们需要new 来开辟新的内存区执行拷贝。还要注意一个问题。我们这个图实际上是个有向图,如果A有一个相邻顶点B,则A->B, 但是B能否到A取决于B是否有相邻顶点A. 也就是说如果B能达到A,说明图中存在环,如果不考虑环的存在,我们在拷贝中可能形成死循环。

\

假设我们从图的A点出发,进行拷贝得到A(A2), 发现A有一个相邻顶点B,然后进行拷贝得到B(B2),然后链接A2->B2,使得B2成为A2的相邻顶点。接着,我们操作B, 发现B有一个相邻顶点A, 而A我们是已经进行过拷贝的了。如果我们又对A再次进行拷贝, 将形成个死循环,我们要做的仅是将B2->A2连接起来。如何才能避免这种再次拷贝呢?我们只需要一个map即可,每次我们做一份拷贝,就放入map中,下次查询,如果是已经有的copy就不再继续拷贝,只是连接。如果没有,就做拷贝,然后连接,然后放入map. map的key是原来的顶点,value是原来定点的copy版。<??http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+vt/M5b3iys2/ydLUv7TPwtXixqrOxNXCo7pjbG9uZSBncmFwaCBwYXJ0PC9wPgo8cD5xdWV1ZdbQzqy7pLXEysfOtLSmwO1uZWlnaGJvcrXEtqW146Os0rLKx860v72xtLn9tcS94bXjoaM8L3A+CjxwPm1hcNbQtcRrZXksdmFsdWW31rHwsaO05mNvcHm5/bXE1K292rXjus1jb3B5vdq146GjPC9wPgo8cD7O0sPHz8hjb3B5uPm94bXjo6zIu7rzt8XI67bTwdCjrL3Tz8LAtL340NC547bI08XPyMvRy/ew7Leoo6yyu7bPtKbA7bbTwdDW0LXEvdq146Osz8i1w7W9tbHHsL3ateO6zcbkY29webDmsb6jrMi7uvPF0LbPtbHHsL3ateO1xMv509BuZWlnaGJvcnMsIMjnufvS0b6tv72xtLn9o6zWu9f2way907LZ1/ejrMjnufvDu9PQv72xtLn9o6zPyL340NC/vbG0o6zIu7rzway906OsyLu687fFyOttYXC6zXF1ZXVlLrWxttPB0NbQtcTUqsvYtry0psDtzeqjrEJGU73hyvijrLe1u9hjb3B5uPm94bXjoaM8L3A+CjxwPjxzdHJvbmc+QXR0ZW50aW9uOjwvc3Ryb25nPjwvcD4KPHA+PHN0cm9uZz7W99Kqyse7+bG+t723qLXEstnX98rHt/HKudPD1f3It6OsvNPJz9K70KnPuL3atcSy2df3o6zQ6NKq19DPuMDtveK6zbzH0uSho8r009q7+bG+stnX97XE1+m6z6OsyN3S17vsz/2jrNOmuMPX0M+40dC+v8/CtPrC66GjPC9zdHJvbmc+PC9wPgo8cD48c3Ryb25nPjEuINei0uK7+bG+stnX97XEyrnTw6OsscjI573hubnM5da41eu1xMTasr/UqsvYtcS199PDysfTw8TEuPay2df3t/ujvw=="->"还是"." 还有分清楚操作的对象,然后决定用C++内的什么方法进行调用和操作。

curClone->neighbors.push_back(neighborClone);     // 给curClone添加复制的neighbor

2. 注意我们在拷贝过程中,总是要对原节点进行拷贝,处理连接关系时,也要在拷贝版本间进行连接。

 curClone->neighbors.push_back(neighborClone);     // 给curClone添加复制的neighbor

3. map添加pair对,需要加“{}”。

cmap.insert({neighbor, neighborClone});   //添加到map中

复杂度:O(N),因为我们把每个结点都访问一遍,空间复杂度是栈或者队列加上map的大小,不会超过O(N)。

AC Code: (BFS)

/**
 * Definition for undirected graph.
 * struct UndirectedGraphNode {
 *     int label;
 *     vector
    
      neighbors;
 *     UndirectedGraphNode(int x) : label(x) {};
 * };
 */
class Solution {
public:
    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
        if(node == NULL) return NULL;
        
        //开辟新的空间存储copy
        UndirectedGraphNode* copy = new UndirectedGraphNode(node->label);
        //查找去重用的map  unordered_map
     
       放原始node和其复制品 unordered_map
      
        cmap; //存储的队列,进行BFS queue
       
         graphQ; graphQ.push(node); //根结点添加到队列 cmap.insert({node, copy}); //把根节点和其复制品放入map while(!graphQ.empty()) { UndirectedGraphNode* cur = graphQ.front(); //当前处理对象 graphQ.pop(); UndirectedGraphNode* curClone = cmap[cur]; //当前处理对象的复制品 因为在前面的neighbor里已经被创建 //对当前顶点的每一个neighbor进行判断,因为有的neighbor已经被复制,有的没有 for(int i = 0; i < cur->neighbors.size(); i++) { UndirectedGraphNode* neighbor = cur->neighbors[i]; //如果之前没有拷贝过 if(cmap.find(neighbor) == cmap.end()) { UndirectedGraphNode* neighborClone = new UndirectedGraphNode(neighbor->label); curClone->neighbors.push_back(neighborClone); //给curClone添加复制的neighbor cmap.insert({neighbor, neighborClone}); //添加到map中 graphQ.push(neighbor); //添加到队列为了将来的遍历 } else // 之前已经被复制过的neighbor { UndirectedGraphNode* neighborClone = cmap[neighbor]; //从map中取出之前的copy版本 curClone->neighbors.push_back(neighborClone); // 给curClone添加复制的neighbor } } } return copy; } };
       
      
     
    


AC Code: (DFS)

将存储改成用stack存储结点,得到深度优先搜索。

/**
 * Definition for undirected graph.
 * struct UndirectedGraphNode {
 *     int label;
 *     vector
    
      neighbors;
 *     UndirectedGraphNode(int x) : label(x) {};
 * };
 */
class Solution {
public:
    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
        if(node == NULL) return NULL;
        stack
     
       stk; unordered_map
      
        cmap; UndirectedGraphNode* copy = new UndirectedGraphNode(node->label); stk.push(node); cmap.insert({node, copy}); while(!stk.empty()) { UndirectedGraphNode* cur = stk.top(); stk.pop(); UndirectedGraphNode* curClone = cmap[cur]; //浅拷贝,开始顶点的curClone和copy指向同一个地址 for(int i = 0; i < cur->neighbors.size(); i++) { UndirectedGraphNode* neighbors = cur->neighbors[i]; if(cmap.find(neighbors) == cmap.end()) { UndirectedGraphNode* neighborsClone = new UndirectedGraphNode(neighbors->label); curClone->neighbors.push_back(neighborsClone); cmap.insert({neighbors, neighborsClone}); stk.push(neighbors); } else { UndirectedGraphNode* neighborsClone = cmap[neighbors]; curClone->neighbors.push_back(neighbo
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇leetcode_6_ZigZag Conversion 下一篇Go语言实现跳表(SkipList)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·微服务 Spring Boot (2025-12-26 18:20:10)
·如何调整 Redis 内存 (2025-12-26 18:20:07)
·MySQL 数据类型:从 (2025-12-26 18:20:03)
·Linux Shell脚本教程 (2025-12-26 17:51:10)
·Qt教程,Qt5编程入门 (2025-12-26 17:51:07)