复制复杂链表,链表结构如下:
static class Node{
public char value;
public Node nextNode;
public Node siblingNode;
@Override
public String toString() {
String str = "Node [value=" + value;
if(nextNode == null)
str += ", nextNode=null";
else
str += ", nextNode=" + nextNode.value;
if(siblingNode == null)
str+= ", siblingNode=null";
else
str += ", siblingNode=" + siblingNode.value;
str +="]";
return str;
}
}
思路:第一遍不复制siblingNode,只复制value和nextNode;
第二遍复制siblingNode
分析:复制siblingNode时,对每一个Node要花O(n)时间寻找siblingNode,总时间复杂度为O(n2)
改进1:利用O(n)空间建立哈希表,则复制siblingNode的时间花费降低至O(n)
改进2:设原链表为A-B-C-D-E,第一遍复制时直接在复制的Node后面添加,变为A-A'-B-B'-C-C'-D-D'-E-E'
这样当第二遍寻找siblingNode时,A的sibingNode的后一个Node就是A'的siblingNode,
最后将链表分开即可。
改进2代码如下:
package com.zxy.exercise;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
//复制复杂链表
Node nodeA = new Node();
Node nodeB = new Node();
Node nodeC = new Node();
Node nodeD = new Node();
Node nodeE = new Node();
nodeA.value = 'a';
nodeA.nextNode = nodeB;
nodeA.siblingNode = nodeC;
nodeB.value = 'b';
nodeB.nextNode = nodeC;
nodeB.siblingNode = nodeE;
nodeC.value = 'c';
nodeC.nextNode = nodeD;
nodeC.siblingNode = null;
nodeD.value = 'd';
nodeD.nextNode = nodeE;
nodeD.siblingNode = nodeB;
nodeE.value = 'e';
nodeE.nextNode = null;
nodeE.siblingNode = null;
Node copyHeadNode = copyList(nodeA);
Node pNode = copyHeadNode;
while(pNode != null){
System.out.println(pNode.toString());
pNode = pNode.nextNode;
}
}
public static Node copyList(Node head){
if(head == null)
return null;
copyNode(head);
copySibling(head);
return devideList(head);
}
//a-b-c-d-e --> a-a-b-b-c-c-d-d-e-e
private static void copyNode(Node head){
Node pNode = head;
while(pNode != null){
Node node = new Node();
node.value = pNode.value;
node.nextNode = pNode.nextNode;
node.siblingNode = null;
pNode.nextNode = node;
pNode = node.nextNode;
}
}
//补齐sibling
private static void copySibling(Node head){
Node pNode = head;
Node cNode = pNode.nextNode;
while(pNode != null){
if(pNode.siblingNode != null)
cNode.siblingNode = pNode.siblingNode.nextNode;
pNode = cNode.nextNode;
if(pNode != null)
cNode = pNode.nextNode;
}
}
//将链表分开
private static Node devideList(Node head){
Node pNode = head;
Node cHeadNode = head.nextNode;
Node cNode = head.nextNode;
while(pNode != null){
pNode.nextNode = cNode.nextNode;
pNode = pNode.nextNode;
if(pNode == null)
break;
cNode.nextNode = pNode.nextNode;
cNode = cNode.nextNode;
}
return cHeadNode;
}
static class Node{
public char value;
public Node nextNode;
public Node siblingNode;
@Override
public String toString() {
String str = "Node [value=" + value;
if(nextNode == null)
str += ", nextNode=null";
else
str += ", nextNode=" + nextNode.value;
if(siblingNode == null)
str+= ", siblingNode=null";
else
str += ", siblingNode=" + siblingNode.value;
str +="]";
return str;
}
}
}