方法一:
分析题意,要判断两个链表是否相交,即判断它们的节点地址是否相同,利用set容器,先将链表A节点地址添加到set中,再遍历链表B并利用set的泛型算法判断B中是否有在A中出现过的节点,有则将其返回 (set底层是红黑树)
时间复杂度:O(nlogn)
空间复杂度:O(n)
/**
* 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) {
set<ListNode*> check_set;//利用STL找出数组a与b中重复出现的元素
ListNode* result = nullptr;//存储两个相交的节点
while(headA)//遍历链表A
{
check_set.insert(headA);//将链表A的节点地址添加至check_set
headA = headA->next;
}
while(headB)//遍历链表B
{
if (check_set.find(headB) != check_set.end())//判读B中是否有在A中出现过的节点
{
result = headB;//第一个重复的节点
break;
}
headB = headB->next;
}
return result;
}
};
方法二:首先比较两个链表的长度,将两个链表的头指针移至相同的位置,这时侯让两个链表的头指针一起往后移动一格,当这两个指针相等时即为所求
时间复杂度:O(n)
空间复杂度:O(1)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
//计算链表长度
int List_Length(ListNode * head)
{
int length = 0;
while(head)
{
length++;
head = head->next;
}
return length;
}
//移动节点
ListNode *Move_Pointer(ListNode* head,int count)
{
for(int i = 0; i < count; i++)//向后移动count
{
head = head->next;
}
return head;
}
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int lengthA = List_Length(headA);
int lengthB = List_Length(headB);
if (lengthA > lengthB)//谁大移动谁
{
headA = Move_Pointer(headA,lengthA - lengthB);
}
else
{
headB = Move_Pointer(headB,lengthB - lengthA);
}
ListNode* result = nullptr;//存储交点地址
while(headA && headB)//同时移动A和B
{
if(headA == headB)//找到相交的节点
{
result = headA;
break;
}
headA = headA->next;
headB = headB->next;
}
return result;
}
};