题目描述

  • 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)。
  • 复制一个复杂链表

结点定义

  1. class RandomListNode {
  2. int label;
  3. RandomListNode next = null;
  4. RandomListNode random = null;
  5. public RandomListNode(int label){
  6. this.label = label;
  7. }
  8. }

解析

  • 遍历链表,每个结点后边复制相同的结点,设置next指针
  • 复制结点的特殊指针。如果原始链表上的结点N的random指向S,则它对应的复制结点N的random指向S的下一个结点S
  • 抽取复制结点,连起来得到复制链表

代码实现

  1. public RandomListNode clone(RandomListNode pHead){
  2. cloneNodes(pHead);
  3. connectRandomNodes(pHead);
  4. return reconnectNodes(pHead);
  5. }
  6. //复制原始链表的任意结点N并创建新结点N`,再把N`链接到N的后面
  7. private void cloneNodes(RandomListNode pHead) {
  8. RandomListNode curNode = pHead;
  9. while(curNode != null){
  10. RandomListNode nextNode = curNode.next;
  11. RandomListNode copyNode = new RandomListNode(curNode.label);
  12. copyNode.next = nextNode;
  13. copyNode.random = null;
  14. curNode.next = copyNode;
  15. curNode = copyNode.next;
  16. }
  17. }
  18. //如果原始链表上的结点N的random指向S,则它对应的复制结点N`的random指向S的下一个结点S`
  19. private void connectRandomNodes(RandomListNode pHead) {
  20. RandomListNode curNode = pHead;
  21. while(curNode != null){
  22. RandomListNode copyNode = curNode.next;
  23. if(curNode.random != null){
  24. copyNode.random = curNode.random.next;
  25. }
  26. curNode = copyNode.next;
  27. }
  28. }
  29. //组合复制的结点
  30. private RandomListNode reconnectNodes(RandomListNode pHead) {
  31. RandomListNode curNode = pHead;
  32. RandomListNode copyHead = null;
  33. RandomListNode copyNode = null;
  34. //设置头结点
  35. if(curNode != null){
  36. copyHead = curNode.next;
  37. copyNode = curNode.next;
  38. curNode.next = copyNode.next;
  39. curNode = curNode.next;
  40. }
  41. while(curNode != null){
  42. copyNode.next = curNode.next;
  43. copyNode = copyNode.next;
  44. curNode.next = copyNode.next;
  45. curNode = curNode.next;
  46. }
  47. return copyHead;
  48. }