Leetcode 133. Clone Graph & 138. Copy List with Random Pointer
来源:互联网 发布:大数据徐子沛 编辑:程序博客网 时间:2024/06/05 14:27
因为自己是先做的138,先说138。参考这里。
138. Copy List with Random Pointer
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.
这题有两种解法。
解法一:
O(n)空间+O(n)时间。
先按照原list复制一遍,先不复制random point,这是第一遍,但是需要建立结点的对应关系,比如原来的1对应现在的1;2对应2。
然后第二遍从到到尾,新list元素的random元素即是map.get(原数组元素.random)。比如原来1.random = 3,那么当前1的random就是原来3对应的节点,用map取出。
蓝色为原始链表节点,紫红色为新链表节点:
/** * Definition for singly-linked list with a random pointer. * class RandomListNode { * int label; * RandomListNode next, random; * RandomListNode(int x) { this.label = x; } * }; */public class Solution { public RandomListNode copyRandomList(RandomListNode head) { if(head==null) return null; HashMap<RandomListNode, RandomListNode> hm = new HashMap<RandomListNode, RandomListNode>(); RandomListNode newHead = new RandomListNode(head.label); hm.put(head, newHead); RandomListNode tail = newHead; RandomListNode cur = head.next; while(cur!=null){ RandomListNode newcur = new RandomListNode(cur.label); hm.put(cur, newcur); cur = cur.next; tail.next = newcur; tail = tail.next; } cur = newHead; while(head!=null){ cur.random = hm.get(head.random); head = head.next; cur = cur.next; } return newHead; }}
解法二:
O(n)时间,O(1)空间。
第一遍,复制原结点。要求是将复制的点放在该结点之后,以便后来找对应的结点。比如1 -> 2 -> 3复制完变成1 -> 1-> 2-> 2-> 3-> 3->。
第二遍,复制random 指针。cur.next.random = cur.random.next。
第三遍,分离两个list。
一开始想两遍做,结果当然是不行的,因为random指针有可能指向之前的元素。
/** * Definition for singly-linked list with a random pointer. * class RandomListNode { * int label; * RandomListNode next, random; * RandomListNode(int x) { this.label = x; } * }; */public class Solution { public RandomListNode copyRandomList(RandomListNode head) { if(head==null) return null; RandomListNode cur = head; while(cur.next!=null){ RandomListNode next = cur.next; cur.next = new RandomListNode(cur.label); cur.next.next = next; cur = next; }// arrive at last node cur.next = new RandomListNode(cur.label); cur = head; RandomListNode newhead = head.next; RandomListNode newcur = newhead; while(cur!=null){ if(cur.random != null) cur.next.random = cur.random.next; cur = cur.next.next; } cur = head; newcur = newhead; while(cur!=null){ cur.next = newcur.next; cur = cur.next; newcur.next = cur.next; newcur = newcur.next; } return newhead; }}
133. Clone Graph
Clone an undirected graph. Each node in the graph contains a label
and a list of its neighbors
.
OJ's undirected graph serialization:
Nodes are labeled uniquely.
We use#
as a separator for each node, and ,
as a separator for node label and each neighbor of the node.As an example, consider the serialized graph {0,1,2#1,2#2,2}
.
The graph has a total of three nodes, and therefore contains three parts as separated by #
.
- First node is labeled as
0
. Connect node0
to both nodes1
and2
. - Second node is labeled as
1
. Connect node1
to node2
. - Third node is labeled as
2
. Connect node2
to node2
(itself), thus forming a self-cycle.
Visually, the graph looks like the following:
1 / \ / \ 0 --- 2 / \ \_/
感觉这类复制题,都是加一些额外的限制。比如138题有random的限制,你需要找对应关系。
而这道题,也一样加了限制,就是每个点相连的点有可能重复。也就是说仍然需要对应关系来知道这个点是否已经存在。
参考自code ganker:http://blog.csdn.net/linhuanmars/article/details/22715747
思路:
1. BFS。每次取一个点。然后check table中有没有这个点的key,如果有,说明已经创建过了,只需要更新入结点的neighbor就行了;如果没有则创建之,映射关系存入map,并加入queue待下次遍历其neighbor。
/** * Definition for undirected graph. * class UndirectedGraphNode { * int label; * List<UndirectedGraphNode> neighbors; * UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); } * }; */public class Solution { // BFS public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { if(node==null) return null; HashMap<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<UndirectedGraphNode, UndirectedGraphNode>(); LinkedList<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>(); UndirectedGraphNode newnode = new UndirectedGraphNode(node.label); map.put(node, newnode); queue.add(node); while(queue.size()!=0){ UndirectedGraphNode cur = queue.poll(); for(UndirectedGraphNode neighbor : cur.neighbors){ if(!map.containsKey(neighbor)){ newnode = new UndirectedGraphNode(neighbor.label); map.put(neighbor, newnode); queue.add(neighbor); } map.get(cur).neighbors.add(map.get(neighbor)); } } return map.get(node); }}
2.DFS。
跟BFS的不同是,BFS是遇到一个没访问过的点,则创建之并加入队尾,每次取队首元素,这样就先遍历了所有该结点的邻居,再从邻居出发遍历。
DFS则是每次取队尾元素。
/** * Definition for undirected graph. * class UndirectedGraphNode { * int label; * List<UndirectedGraphNode> neighbors; * UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); } * }; */public class Solution { // DFS public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { if(node==null) return null; HashMap<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<UndirectedGraphNode, UndirectedGraphNode>(); LinkedList<UndirectedGraphNode> stack = new LinkedList<UndirectedGraphNode>(); UndirectedGraphNode newnode = new UndirectedGraphNode(node.label); map.put(node, newnode); stack.push(node); while(stack.size()!=0){ UndirectedGraphNode cur = stack.pop(); for(UndirectedGraphNode neighbor : cur.neighbors){ if(!map.containsKey(neighbor)){ newnode = new UndirectedGraphNode(neighbor.label); map.put(neighbor, newnode); stack.push(neighbor); } map.get(cur).neighbors.add(map.get(neighbor)); } } return map.get(node); }}
DFS用递归实现:
碰到新节点,创建,入map,然后立即调用helper。
/** * Definition for undirected graph. * class UndirectedGraphNode { * int label; * List<UndirectedGraphNode> neighbors; * UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); } * }; */public class Solution { // DFS recursive public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { if(node==null) return null; HashMap<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<UndirectedGraphNode, UndirectedGraphNode>(); UndirectedGraphNode newnode = new UndirectedGraphNode(node.label); map.put(node, newnode); helper(node, map); return map.get(node); } void helper(UndirectedGraphNode node, HashMap<UndirectedGraphNode, UndirectedGraphNode> map){ for(UndirectedGraphNode neighbor : node.neighbors){ if(!map.containsKey(neighbor)){ UndirectedGraphNode newnode = new UndirectedGraphNode(neighbor.label); map.put(neighbor, newnode); helper(neighbor, map); } map.get(node).neighbors.add(map.get(neighbor)); } }}
所有方法的时间复杂度和空间复杂度都是O(n)。
- Leetcode 133. Clone Graph & 138. Copy List with Random Pointer
- [LeetCode]Copy List with Random Pointer &Clone Graph 复杂链表的复制&图的复制
- LeetCode 138. Copy List with Random Pointer
- [Leetcode] 138. Copy List with Random Pointer
- LeetCode 138. Copy List with Random Pointer
- [leetcode] 138. Copy List with Random Pointer
- LeetCode 138. Copy List with Random Pointer
- LeetCode 138. Copy List with Random Pointer
- leetcode.138. Copy List with Random Pointer
- LeetCode-138.Copy List with Random Pointer
- Leetcode 138. Copy List with Random Pointer
- [Leetcode]138. Copy List with Random Pointer
- LeetCode 138. Copy List with Random Pointer
- [LeetCode] 138. Copy List with Random Pointer
- [LeetCode]138. Copy List with Random Pointer
- LeetCode 138. Copy List with Random Pointer
- Leetcode-138. Copy List with Random Pointer
- Leetcode 138. Copy List with Random Pointer
- LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal(根据中序遍历和后序遍历构造二叉树)
- LeetCode 107. Binary Tree Level Order Traversal II(二叉树分层遍历)
- LeetCode 108. Convert Sorted Array to Binary Search Tree(数组转换为二叉搜索树)
- LeetCode 109. Convert Sorted List to Binary Search Tree(链表到二叉搜索树)
- leetcode #24 in cpp
- Leetcode 133. Clone Graph & 138. Copy List with Random Pointer
- LeetCode 110. Balanced Binary Tree(平衡二叉树)
- LeetCode 111. Minimum Depth of Binary Tree(二叉树最小深度)
- LeetCode 112. Path Sum(路径和)
- 软件架构设计原则和模式(上):分层架构设计
- 最新的版的PostgresSQL引入了BRIN索引
- LeetCode 113. Path Sum II(路径和)
- LeetCode 114. Flatten Binary Tree to Linked List(摊平二叉树)
- WindowBuilder的离线安装与使用