题目:
给定两个(单向)链表,判定它们是否相交并返回交点。请注意相交的定义基于节点的引用,而不是基于节点的值。换句话说,如果一个链表的第k个节点与另一个链表的第j个节点是同一节点(引用完全相同),则这两个链表相交。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB)
{
unordered_set<ListNode*> hash;
ListNode* node1 = headA, * node2 = headB;
while(node1 != nullptr)
{
hash.insert(node1);
node1 = node1->next;
}
while(node2 != nullptr)
{
if(hash.count(node2) > 0) return node2;
node2 = node2->next;
}
return nullptr;
}
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
/*
题解:题目要求是求出两个链表交点的指针,这里的交点不是指数值相等,而是指针相等
刚开始想错了,这里是节点,可不是直线,不能与直线相交混淆了啊!!!
从某个节点开始一旦相交,那么后面的都是是相等的,这里的相交其实是可以理解为 重合 ,地址相等 + 值相等
正是因为如此,如果两个链表相交的话,尾部一定是相等的!即从中间某处开始 到尾部 是完全相等(重合)!!!
*/
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB)
{
if(headA == nullptr || headB == nullptr) return nullptr;
ListNode* tempA = headA;
ListNode* tempB = headB;
int lenA = 0;
int lenB = 0;
// 一定得先分清楚 两个链表谁比较长,所以需要先求长度
while(tempA != nullptr)
{
lenA++;
tempA = tempA->next;
}
while(tempB != nullptr)
{
lenB++;
tempB = tempB->next;
}
// 1::两个while完成后,临时节点为位置已经都变成空节点了,所以这里要重新赋值一下
tempA = headA;
tempB = headB;
// 2::将A定为比较大的那个,如果B大,则交换,注意这里的交换,可以直接用 swap函数。我都不知道
if(lenB > lenA)
{
swap(tempA, tempB);
swap(lenA, lenB);
}
int count = lenA - lenB;
while(count)
{
tempA = tempA->next;
count--;
}
// 上面这个while循环可以替换为 : while(count--) tempA = tempA->next;
// 这里这个 while 循环可以改一下,将判断条件设置为 tempA != nullptr,这样就不用多做一次减法
while(lenB)
{
if(tempA == tempB)
{
return tempA;
}
tempA = tempA->next;
tempB = tempB->next;
lenB--;
}
return nullptr;
}
};