部分文章内容为公开资料查询整理,原文出处可能未标注,如有侵权,请联系我,谢谢。邮箱地址:gnivor@163.com ►►►需要气球么?请点击我吧!

编程之美--3.6编程判断两个链表是否相交

给出两个单向链表的头指针,比如h1、h2,判断两个链表是否相交。为了简化问题,假设两个链表均不带环。

解法1:在第一个链表中依次查找第二个链表中的元素是否在第一个链表中(不可取)

解法2:如果链表节点相交,那么相交节点的地址一定相同。可以将第一个链表各个节点的地址存放在Hash表中,然后在表中查询第二个链表的各个节点的地址。如果在hash表中出现,那么证明两个链表有公共节点。时间复杂度O(length(h1)+length(h2)),需要额外开辟空间O(length(h1))。

解法3:第二个链表连接到第一个链表之后,如果两个链表原来不相交,那么合并后没有环; 如果两个链表原来相交,那么合并后必然有环。

解法4:如果两个链表相交,两链表尾部必然指向同一个元素。因此遍历两个链表到尾节点,如果地址相同,则链表相交。时间复杂度O(length(h1)+length(h2))

代码:

public static boolean IsIntersect(Node n1, Node n2){
    Node p1 = n1;
    Node p2 = n2;
    while(p1.next!=null) p1=p1.next;
    while(p2.next!=null) p2=p2.next;
        
    return p1==p2?true:false;
}


class Node{
    public int data;
    public Node next;
    public Node(int data,Node next){
        this.data=data;
        this.next=next;
    }
}

 

扩展:怎么确定第一个重合节点?

方法:根据解法4,首先遍历两个链表,计算长度分别为len1,len2。我们假设len1>len2, k=len1-len2,那么先将链表1的指针p1向后移动k个节点,然后比较p1、p2指向节点的地址是否相同,同时向后移动p1、p2,知道找到地址相同的节点。这个节点就是第一个重合节点。

 

扩展2:链表有环呢?

方法:指向链表1的指针p1,链表2的指针p2。可以先遍历一遍使两个指针都在环上。指针p1每次向前移动一个节点,指针p2每次向前移动两个节点。如果p1、p2重合,那么两个链表有相交节点。如果p1在回到之前经过的某个节点之前仍然没有和p2相遇,则两个链表不相交。

posted @ 2015-06-28 16:32  流了个火  阅读(96)  评论(0)    收藏  举报
►►►需要气球么?请点击我吧!►►►
View My Stats