题目
思路
法一 :暴力
- A链表的节点跟B链表的所有节点比较,直到A链表中的某个节点和B链表中的某个节点相等这个节点就是交点
- 就是A链表的第一个节点和B链表的所有节点比较,A链表节点再往后走,直到相等
- 时间复杂度:O(NN)或O(NM)
因为A链表M个节点,B链表N个节点,A链表节点走一步,B链表节点走N步
所以A链表走M步,B链表走N*M步
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{
ListNode* prev = headA;
ListNode* pcur = headB;
again:
while(pcur != prev)
{
if(pcur == NULL)
break;
//pcur 等于空就遍历完一遍了
pcur = pcur->next;
}
if(pcur == prev)
return pcur;
//遍历到 pcur 和 prev相等,就在同一个节点上 空或者非空
pcur = headB;
//不相等,重新头开始
prev = prev->next;
//prev走到下一个节点
goto again;
// 一遍一遍循环,直到 prev = pcur
}
思路
法二 :
- 区分:相不相交找尾,如果尾的地址相同链表就相交,注意不是链表指向的值相同,如果链表不相交,而最后一个值也可以是相同的
- 用假设法,判断A链表长,B链表短,否则,B链表长,A链表短,长的链表走差距步,然后长短链表同时走,
两个指针就指向了第一个相交的节点了
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{
//1.找尾,尾部的节点地址相同,链表就相交
ListNode* curA = headA,*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;
}
curA = headA;
curB = headB;
//2.让长的链表先走它们的差值个节点
//假设法:假设A链表比B链表长
int gap = lenA-lenB;
ListNode* longList = curA;
ListNode* shortList = curB;
if(lenB>=lenA)
{
longList = curB;
shortList = curA;
gap = lenB - lenA;
}
//长的链表先走差距步大小
while(gap--)
{
longList = longList->next;
}
//让长链表和短链表从同一起点开始走相同的步数大小
while(longList != shortList)
{
shortList = shortList->next;
longList = longList->next;
}
//指向长短链表的指针指向了起始节点(相同节点)
return shortList;
}
结语
望博友们多多支持,祝福我们题题AC