写在前面:我写博客主要是为了对知识点的总结、回顾和思考,把每篇博客写得通俗易懂是我的原则,因为能让别人看懂,才是真的学会了
从Math到CS的跨专业经历,让我格外珍惜学习时间,更加虚心好学,而分享技术和知识是快乐的,非常欢迎大家和我一起交流学习,期待与您的进一步交流
题目描述
算法1
(线性扫描)
(1) 设两个链表的长度分别为a + c和b + c(c是它们相交的一段长度)
(2) 用两个指针p, q分别指向两个链表,p走a + c步后,让p = 另一个链表的起点,然后继续走,q走b + c步后,让q = 另一个链表的起点,然后继续走
(3) 最后如果p和q相同且不是NULL,则它们相交,返回p或q即可
时间复杂度是 ,空间复杂度是
代码
/**
* 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) {
// p and q both move a + b + c
auto p = headA;
auto q = headB;
while(p != q) {
if (p) p = p->next;
else p = headB;
if (q) q = q->next;
else q = headA;
}
return p;
}
};
算法2
(哈希)
- 建立一个哈希表,存链表headA中的结点,键值对为
<ListNode*, int>
- 遍历链表headB中的结点,看是否存在于哈希表中
时间复杂度是 ,空间复杂度是
代码
/**
* 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 p = headA, q = headB;
// Traversing the fisr linked list
while(p != NULL) {
hash[p] = 1;
p = p->next;
}
while(q != NULL) {
if (hash.count(q)) return q;
q = q->next;
}
return NULL;
}
};