zoukankan      html  css  js  c++  java
  • 剑指offer面试题26:复杂链表的复制


    题目:请实现一个函数,复制一个复杂链表。

    在复杂链表中,每个结点除了有一个next指针指向下一个结点外,还有一个sibling指针指向链表中的任意结点或者nulL

    直观解法:

    1.遍历链表,复制链表节点,并连接next节点。2.遍历链表,连接sibling节点。对于一个有n个节点的链表,由于定位每个节点的silbing节点都需要从链表的头结点开始经过O(n)步才能实现,因此这种方法的时间复杂度是O(n2)

    优化解法:上述方法的时间主要是用在了sibling节点的定位上,考虑优化此步骤。具体的做法是在复制节点的时候,把原节点N和复制出来的N'节点用一个map保存起来,这样在第二部连接sibling结点的时候就可以以O(1)的时间复杂度定位到相应的sibling节点,总体时间复杂度为O(n),空间复杂度也是O(n)

    最优算法:

    第一步:根据原始链表的每个节点创建对应的复制结点,把复制结点连接在原结点的后面
    第二步:设置复制出来的结点的任意结点sibling节点
    第三步:把长链表拆分成两个链表

      1 package Solution;
      2 
      3 public class No26CopyComplexList {
      4 
      5     static class ComplexListNode{
      6         int value;
      7         ComplexListNode next;
      8         ComplexListNode sibling;
      9         public ComplexListNode(){
     10             
     11         }
     12         public ComplexListNode(int value,ComplexListNode next,ComplexListNode sibling){
     13             this.value=value;
     14             this.next=next;
     15             this.sibling=sibling;
     16         }
     17     }
     18     
     19     //把复杂链表中的所有结点进行复制,并连接在原结点的后面
     20     private static void cloneNode(ComplexListNode head){
     21         ComplexListNode node=head;
     22         while(node!=null){
     23             ComplexListNode clonedNode=new ComplexListNode();
     24             clonedNode.value=node.value;
     25             clonedNode.next=node.next;
     26             clonedNode.sibling=null;
     27             node.next=clonedNode;
     28             node=clonedNode.next;
     29         }
     30     }
     31     //设置复制的节点的指向任意结点的连接关系
     32     private static void connectSiblingNodes(ComplexListNode head){
     33         ComplexListNode node=head;
     34         while(node!=null){
     35             ComplexListNode clonedNode=node.next;
     36             if(node.sibling!=null){
     37                 clonedNode.sibling=node.sibling.next;
     38             }
     39             node=clonedNode.next;
     40         }
     41     }
     42     //把长链表拆分成两个单独的链表,并返回复制后的链表的头结点
     43     private static ComplexListNode reconnectNodes(ComplexListNode head){
     44         ComplexListNode node=head;
     45         ComplexListNode clonedHead=null;
     46         ComplexListNode clonedNode=null;
     47         if(node!=null){
     48             clonedHead=clonedNode=node.next;
     49             node.next=clonedNode.next;
     50             node=clonedNode.next;
     51         }
     52         while(node!=null){
     53             clonedNode.next=node.next;
     54             clonedNode=node.next;
     55             node.next=clonedNode.next;
     56             node=clonedNode.next;
     57         }
     58         return clonedHead;
     59     }
     60     public static ComplexListNode copyComplexList(ComplexListNode head){
     61         if(head==null)
     62             return null;
     63         cloneNode(head);
     64         connectSiblingNodes(head);
     65         return reconnectNodes(head);
     66     }
     67     
     68     public static void printComplexList(ComplexListNode head){
     69         ComplexListNode node=head;
     70         int  value=0;
     71         ComplexListNode next=null;
     72         ComplexListNode sibling=null;
     73         while(node!=null){
     74             value=node.value;
     75             next=node.next;
     76             sibling=node.sibling;
     77             StringBuilder sb=new StringBuilder("当前节点的值为:").append(value);
     78             if(next!=null)
     79                 sb.append(",下一结点的值为:").append(next.value);
     80             else
     81                 sb.append(",当前结点为尾节点");
     82             if(sibling!=null)
     83                 sb.append(",指向任意结点的值为:").append(sibling.value);
     84             else
     85                 sb.append(",没有指向其他结点的任意结点");
     86             System.out.println(sb.toString());    
     87             node=node.next;
     88         }
     89     }
     90     public static void main(String[] args) {
     91         ComplexListNode node1=new ComplexListNode();
     92         ComplexListNode node2=new ComplexListNode();
     93         ComplexListNode node3=new ComplexListNode();
     94         ComplexListNode node4=new ComplexListNode();
     95         ComplexListNode node5=new ComplexListNode();
     96         node1.value=1;
     97         node1.next=node2;
     98         node1.sibling=node3;
     99         node2.value=2;
    100         node2.next=node3;
    101         node2.sibling=node5;
    102         node3.value=3;
    103         node3.next=node4;
    104         node3.sibling=null;
    105         node4.value=4;
    106         node4.next=node5;
    107         node4.sibling=node2;
    108         node5.value=5;
    109         node5.next=null;
    110         node5.sibling=null;
    111         printComplexList(node1);
    112         System.out.println("=========================开始复制============================");
    113         printComplexList(copyComplexList(node1));
    114     }
    115 }
  • 相关阅读:
    go语言关于线程与通道channal
    linux 搭建SVN服务端
    使用mbedtls的使用说明和AES加密方法(原来的PolarSSL)
    清理 Xcode 10 记录
    Windows下修改iTunes备份路径
    Winform窗口自适应
    修改类模板文件
    HashTable
    修改App.config的键和值
    博客园动画效果
  • 原文地址:https://www.cnblogs.com/gl-developer/p/7296522.html
Copyright © 2011-2022 走看看