力扣对应题目链接:160. 相交链表 - 力扣(LeetCode)
牛客对应题目链接:两个链表的第一个公共结点_牛客题霸_牛客网 (nowcoder.com)
核心考点 :单链表理解,临界条件判定。
一、《剑指Offer》对应内容
二、分析题目
题目要求是单链表,所以如果有交点,则最后一个链表的节点地址一定是相同的。
求第一公共节点,本质是让长的链表先走 abs(length1-length2) 步,后面大家的步调一致,往后找第一个地址相同的节点,就是题目要求的节点,所以需要各自遍历两次链表。
三、代码
//力扣
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
int getLength(ListNode* list)
{
if(list==NULL) return 0;
int len=0;
while(list)
{
len++;
list=list->next;
}
return len;
}
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headA==NULL || headB==NULL) return NULL;
int length1=getLength(headA);
int length2=getLength(headB);
if(length1>=length2)
{
int step=length1-length2;
while(step--)
{
headA=headA->next;
}
}
else
{
int step=length2-length1;
while(step--)
{
headB=headB->next;
}
}
while(headA && headB)
{
if(headA==headB) return headA;
headA=headA->next;
headB=headB->next;
}
return NULL;
}
};
//牛客
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
int GetListLength(ListNode* list)
{
if(list==nullptr) return 0;
int len=0;
while(list)
{
len++;
list=list->next;
}
return len;
}
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1==nullptr || pHead2==nullptr) return nullptr;
int length1=GetListLength(pHead1);
int length2=GetListLength(pHead2);
if(length1>=length2)
{
int step=length1-length2;
while(step--)
{
pHead1=pHead1->next;
}
}
else
{
int step=length2-length1;
while(step--)
{
pHead2 = pHead2->next;
}
}
while(pHead1 && pHead2)
{
if(pHead1==pHead2)
return pHead1;
pHead1=pHead1->next;
pHead2=pHead2->next;
}
return nullptr;
}
};
四、扩展
如果把图 5.3 逆时针旋转 90°,我们就会发现两个链表的拓扑形状和一棵树的形状非常相似,只是这里的指针是从叶结点指向根节点的。两个链表的第一个公共结点正好就是二叉树中两个叶节点的最低公共祖先。