Exercise——CopyComplexList

复制复杂链表,链表结构如下:

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;
		}
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值