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 }
  • 相关阅读:
    centos7.6 安装与配置 MongoDB yum方式
    MongoDB 介绍
    centos 关闭selinux
    前端 HTML标签属性
    前端 HTML 标签嵌套规则
    前端 HTML 标签分类
    前端 HTML body标签相关内容 常用标签 表单标签 form里面的 input标签介绍
    前端 HTML body标签相关内容 常用标签 表单标签 form 表单控件分类
    前端 HTML form表单标签 select标签 option 下拉框
    POJ 1426
  • 原文地址:https://www.cnblogs.com/gl-developer/p/7296522.html
Copyright © 2011-2022 走看看