难度简单
给你两个单链表的头节点 headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null
。
图示两个链表在节点 c1
开始相交:
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
方法一:暴力循环 时间复杂度:O(n^2) 空间复杂度O(1)
思路:采用两重循环,依次比较各节点是否相同
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headA == NULL || headB == NULL) return NULL;
for(auto i=headA;i!=NULL;i=i->next){
for(auto j=headB;j!=NULL;j=j->next){
if(i==j) return i;
}
}
return NULL;
}
方法二:借助 hash_map辅助 时间复杂度O(n),空间复杂度O(n)
思路:采用hash_map存储一个链表的各节点信息,遍历另一个链表,发现相同的节点则返回。
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headA == NULL || headB == NULL) return NULL;
unordered_map<ListNode*,bool> data;
while(NULL!=headA){
data.insert({headA,true});
headA=headA->next;
}
while(NULL!=headB){
if(data[headB]) return headB;
headB = headB->next;
}
return NULL;
}
方法三:利用逻辑方式查找 时间复杂度O(n+m),空间复杂度O(1)
思路:根据链表的相交点为最后部分,且若链表 A+B 与链表 B+A等长可采用如下方式判断
① 当指向链表 A 和 指向链表 B 的两个指针不同时
不为 NULL -> 指向当前链表的下一个节点
为 NULL -> 指向另一个链表的开始位置
② 当指向链表 A 和 指向链表 B 的两个指针相同时
返回当前指向的节点 (实际节点 或者 NULL)