思路分析:
首先要明确一个误区,链表相交并不是像十字路口那样交叉,而是像上图这样交叉,其原因在于链表的next只能存储一个位置的地址,因此链表的多个结点可以指向同一个结点,而不能由一个结点指向多个结点,这也是为什么逆置链表错误的原因。
由于有两个链表,因此在进行遍历时需要用到两个指针cura和curb。想找到两个链表相交时共同存在的点,也就想要让两个链表从同一个点开始进行比较直到末尾,因此可以使用cura和curb走不同的步数来解决。首先需要遍历链表,获得链表的长度,从而判断哪个链表长,哪个链表短。在遍历结束后,cura和curb也指向了链表的末尾,可以让它们做一次比较,如果最后一个链表结点都不一样,那么前面的结点更不可能相同,则直接置空即可。如果最后一个结点相同,则说明两个链表一定相交,则开始寻找相交结点。
定义一个gap记录两个链表的差,这样可以让长的链表先走gap步,这样两个链表就相当于同时开始,同时结束。逐一比较两个链表的结点,如果不相同,则继续比对下一个,直至找到了相交结点位置。
代码如下:
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* cura = headA;
ListNode* curb = headB;
int lena = 1, lenb = 1;
while (cura->next)
{
cura = cura->next;
lena++;
}
while (curb->next)
{
curb = curb->next;
lenb++;
}
if (cura != curb) return NULL;//最后一个元素都不相交,直接置空
int gap = abs(lena - lenb);
cura = headA;
curb = headB;
if (lena > lenb)
{
while (gap--)
{
cura = cura->next;
}
}
if(lena<lenb)
{
while (gap--)
{
curb = curb->next;
}
}
while (cura != curb)
{
cura = cura->next;
curb = curb->next;
}
return cura;
}
};