LeetCode 160相交链表Easy
-
题目简述:编写一个程序,找到两个单链表相交的起始节点。
- 如果两个链表没有交点,返回
null
. - 在返回结果后,两个链表仍须保持原有的结构。
- 可假定整个链表结构中没有循环。
- 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。
- 如果两个链表没有交点,返回
-
输入:listA = [4,1,8,4,5] listB = [5,0,1,8,4,5] 输出:8
输入:listA = [0,9,1,2,4] listB = [3,2,4] 输出:2
-
思路:双指针扫描O(n)
- 两个指针分别从两个链表的头部开始扫描,每次分别走一步
- 如果一个指针先走到
null
;则从另一个链表的头部开始走 - 当两个指针指向同一个数时
- 如果指针不是
null
,则指针位置就是相遇点 - 如果指针是
null
,则两个链表不相交
- 如果指针不是
a,b 分别代表两个链表的长度,链表不相交则两个指针分别走 a+b 步后都变成 null。
a,b 分别代表两个链表的长度,c表示相交链表部分的长度,链表相交则两个指针分别走 a+b+c 步后在两链表交汇处相遇。
/**
* 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) {
auto l1 = headA;
auto l2 = headB;
while(l1 != l2)
{
if(l1 != NULL) l1 = l1->next;
else l1 = headB;
if(l2 != NULL) l2 = l2->next;
else l2 = headA;
}
return l1;
}
};
-
思路:哈希表保存链表
A
的所有节点,然后检查链表B
中的每一个结点 bi 是否在哈希表中。若在,则bi 为相交的结点。时间复杂度O(m+n),空间复杂度O(n)注意:哈希表一定是保存链表节点而不是保存链表节点对应的数值val
/**
* 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_map<ListNode*, int> hash;
auto l1 = headA;
while(l1)
{
hash[l1]++;
l1 = l1->next;
}
auto l2 = headB;
while(l2)
{
//if(hash.count(l2) > 0) return l2;//等价写法
if(hash[l2]) return l2;
l2 = l2 ->next;
}
return NULL;
}
};