题目描述:

  输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。

  解题思路:

  本题有以下三种解法:

  第一种:先按照next复制,然后依次添加random指针,添加时需要定位random的位置,定位一次需要一次遍历,需要O(n^2)的复杂度。

  第二种:先按照next复制,然后用一个hashmap保存原节点和复制后节点的对应关系,则用O(n)的空间复杂度使时间复杂度降到了O(n)。

   第三种(最优方法):同样先按next复制,但是把复制后的节点放到原节点后面,则可以很容易的添加random,最后按照奇偶位置拆成两个链表,时间复杂度O(n),不需要额外空间。

  举例:

![](https://img2018.cnblogs.com/blog/1608161/201905/1608161-20190503152726651-930857210.png)
![](https://img2018.cnblogs.com/blog/1608161/201905/1608161-20190503152736226-1294586725.png)
![](https://img2018.cnblogs.com/blog/1608161/201905/1608161-20190503152744499-1216401661.png)

  编程实现(Java):

public class Solution {
public RandomListNode Clone(RandomListNode pHead){
if(pHead==null)
return null;
//(1)先按next复制,但是把复制后的节点放到对应原节点后面
CopyNodes(pHead);
//(2)依次添加random指针
addRandom(pHead);
//(3)按照奇偶位置拆成两个链表
return ReconnectNodes(pHead);
}
//先按next复制,但是把复制后的节点放到对应原节点后面
public void CopyNodes(RandomListNode pHead){
RandomListNode head=pHead;
while(head!=null){
RandomListNode temp=new RandomListNode(head.label);
temp.next=head.next; //复制一个结点,插在对应的原节点的后面
temp.random=null;
head.next=temp;
head=temp.next;
}
}
//依次添加random指针
public void addRandom(RandomListNode pHead){
RandomListNode head=pHead;
while(head!=null){
RandomListNode head_new=head.next;
if(head.random!=null)
head_new.random=head.random.next;
head=head_new.next;
}
}
//按照奇偶位置拆成两个链表
public RandomListNode ReconnectNodes(RandomListNode pHead){
if(pHead==null)
return null;
RandomListNode head=pHead;
RandomListNode pHeadClone=head.next;
RandomListNode headClone=pHeadClone;
while(head!=null){
head.next=headClone.next;
head=head.next;
if(head!=null){
headClone.next=head.next;
headClone=headClone.next;
}
}
return pHeadClone;
}
}

最新文章

  1. fping tcping hping nmap nc
  2. Mysql表分区几种方式
  3. (旧)子数涵数·Flash——影片剪辑的事件操作
  4. 3.Factory Method 工厂方法模式(创建型模式)
  5. mui开发webapp(1)
  6. ScrollView 与ListView 滑动冲突完美解决
  7. Cogs 97. [NOIP2007] 树网的核 Floyd
  8. BigDecimal类型的详情
  9. Uploadify 笔记分享 -- 2014年10月18日
  10. Thinkphp高仿陌陌网页直播
  11. git 签出(恢复)指定文件
  12. helm 持久化部署ingres
  13. JavaScript判断对象是否是NULL
  14. linux jpg文件查找木马
  15. FOB注意事项
  16. CsQuery获取IDomObject元素的完整CSS选择器
  17. 高效获得Linux函数调用栈/backtrace的方法【转】
  18. Linux系统编程【转】
  19. SQL SERVER重置自动编号列(标识列)
  20. 极小极大搜索方法、负值最大算法和Alpha-Beta搜索方法

热门文章

  1. clCreateCommandQueue': was declared deprecated
  2. 加密学教程(Cryptography Tuturials)文件夹
  3. UVA 11021 - Tribles(概率递推)
  4. Extjs显示图片
  5. 通过指针访问C++对象的私有成员
  6. bzoj2132: 圈地计划(无比强大的最小割)
  7. tensorflow在windows操作系统上的安装
  8. Appium - 命令行参数
  9. python 12:list(range(...)) (转化参数列表)
  10. 跳出双重for循环的案例__________跳出了,则不再执行标签ok下的for循环代码