编程之美--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相遇,则两个链表不相交。

浙公网安备 33010602011771号