
如何判断两个链表是否相交,并找出交点,这个问题看似很难,只要掌握了方法,还是很容易解决的。
我们先看一种特殊情况。如果两个链表有交点,且在交点前的节点个数是相等的,如果我们同时等速遍历这两个链表,两个链表一定是同时遍历到交点位置的。我们只需在遍历过程中可以一直比较两个链表的节点是否为同一个节点即可。
当其中的一个链表为另一个链表的一部分呢?此时我们发现,它们的交点位置可以这样求:我们分别求出两个链表的长度,然后记录下它们长度的差值len,我们再从头遍历那个较长的链表,到了第len个节点时,正好就是这两个链表的交点。
延伸这种情况我们可以发现,只要两个链表有交点,那么这个交点、一定是在较长链表第len个节点以及靠后的节点处的,因为它们相交后那部分的长度是相等的。对于两个不确定的链表,我们也可以先找到它们的长度差len,然后找到较长链表的第len个节点,现在问题就变成了刚开始说的那种情况了。
解题步骤可以细分为一下过程:
- 求两个链表的长度和长度差len。
- 找到较长链表第len个节点。
- 同时等速遍历两个链表,判断是否为同一个节点。
- 若一直未找到相同节点,一定是没有交点。
解题代码在这里:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null) {
return null;
}
int lenA = getLength(headA);
int lenB = getLength(headB);
int len = lenA-lenB;//获取到两个链表的长度差值。
ListNode pl=headA,ps=headB;
if(len < 0) {
pl = headB;
ps = headA;
len = lenB - lenA;
}//pl一定是较长的链表,ps一定是较短的链表
while(len>0){
pl=pl.next;
len--;
}//找到较长链表第len个节点。
//现在同时等速遍历这两个链表。
while(pl!=null&&ps!=null){
if(pl==ps){
return pl;
}
pl=pl.next;
ps=ps.next;
}
return null;
}
//求链表长度
private int getLength(ListNode head){
int length=0;
ListNode cur=head;
while(cur!=null){
length++;
cur=cur.next;
}
return length;
}
}
版权声明:本文为weixin_50394543原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。