问题描述
编写一个程序,找到两个单链表相交的起始节点。
例1的第一个相交节点为C1,例2的第一个相交节点是2.
解法一
两个链表都遍历一遍,分别统计两个链表的长度,做差,然后
用快慢指针,让长的先走差值步,然后快慢指针每次往后遍历
一步,当快指针等于慢指针时,便找到了我们要找的值;
代码
/**
* 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 = 0;//链表A的长度
int lenB = 0;//链表B的长度
ListNode pl = headA;//永远指向最长的链表
ListNode ps = headB;//永远指向最短的链表
//统计链表A的长度
while(pl != null) {
pl = pl.next;
lenA++;
}
//统计链表B的长度
while(ps != null) {
ps = ps.next;
lenB++;
}
//遍历完后,ps,pl都指向了链表的末尾,这里
//需要重新指回来
pl = headA;
ps = headB;
//计算长链表比短链表长的值
int len = lenA - lenB;
if(len < 0) {
pl = headB;
ps = headA;
len = lenB-lenA;
}
//快指针先走差值步
while(len != 0) {
pl = pl.next;
len--;
}
//快慢指针一起往后遍历,直到找到相交节点
while(pl != ps) {
pl = pl.next;
ps = ps.next;
}
//pl == ps,返回pl,ps都一样
return pl;
}
}
解法二
两链表逐步往后遍历,当链表A遍历完时,将链表B的头赋值给
链表A,并继续遍历,同理,当链表B遍历完时,将链表A的头赋
值给链表B,并继续遍历,直到两相等为止;
代码
/**
* 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) {
ListNode pA=headA;
ListNode pB=headB;
while(pA!=pB){
//pA若没遍历完,继续往后遍历,遍历完则遍历pB
pA= pA==null ? headB :pA.next;
//pB若没遍历完,继续往后遍历,遍历完则遍历pA
pB= pB==null ? headA :pB.next;
}
return pA;
}
}