一、LeetCode题 160.相交链表 160. 相交链表 - 力扣(LeetCode)
题目描述:
题目中的 相交节点 不只是数值相等,指针也应相等。该题目的求解有两种思路,一种是对齐链表后比较节点是否相等,一种是利用 哈希集合 求解。
1、对齐链表后比较节点是否相等
求出两个链表的长度和差值,让 curA 移动到和 curB 末尾对齐的位置,比较链表内元素是否相等,若相等则为相交节点,返回该节点。
代码:
/**
* 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) {
ListNode* curA = headA;
ListNode* curB = headB;
int lenA=0, lenB=0;
while(curA->next != nullptr){
lenA++;
curA = curA->next;
}
while(curB->next != nullptr){
lenB++;
curB = curB->next;
}
curA = headA;
curB = headB;
if(lenB > lenA){
// 始终让链表A比链表B长
swap(lenA, lenB);
swap(curA, curB);
}
int dis = lenA - lenB;
while(dis--){
curA = curA->next;
}
while(curA != nullptr){
if(curA == curB){
return curA;
}
curA = curA->next;
curB = curB->next;
}
return nullptr;
}
};
2、哈希集合(unordered_set):是一种基于哈希表的数据结构,用于存储不重复的元素,与 set(集合,一个内部自动有序且不含重复元素的容器)不同,unordered_set 不保证元素的有序性,但提供了更快的平均查找时间复杂度。与哈希表相比,它只存储键,而不存储键值对。
常用函数:
(1)insert:插入一个元素到集合中。
std::unordered_set<int> set; set.insert(1);
(2)erase:从集合中移除一个或多个元素。
(3)find:查找一个元素,返回指向该元素的迭代器,如果不存在则返回 end()。
(4)count:统计集合中某个元素的数量,对于 unordered_set 来说,结果只能是 0 或 1。
(5)size:返回集合中元素的数量。
(6)empty:检查集合是否为空。
(7)clear:清空集合中的所有元素。
(8)begin 和 end:返回指向集合开头和结尾的迭代器,用于遍历集合。
思路:遍历链表A中的元素,加入哈希集合中;遍历链表B中的元素,若某个节点位于哈希集合中,则该节点为相交节点,返回该节点。
代码:
/**
* 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* > visited;
ListNode* cur = headA;
while(cur != nullptr){
visited.insert(cur);
cur = cur->next;
}
cur = headB;
while(cur != nullptr){
if(visited.count(cur)){
return cur;
}
cur = cur->next;
}
return nullptr;
}
};
二、LeetCode题 142.环形链表II 142. 环形链表 II - 力扣(LeetCode)
题目描述:
代码:利用哈希集合,判断节点是否已经被添加进哈希集合,若集合中存在该节点,则该节点为入环的第一个节点,返回该节点。(本题也可以利用快慢指针法求解,涉及数学推导,具体可见代码随想录 (programmercarl.com))
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
unordered_set<ListNode* > visited;
while(head != nullptr){
if(visited.count(head)){
return head;
}
visited.insert(head);
head = head->next;
}
return nullptr;
}
};
本文根据代码随想录顺序刷题。代码随想录 (programmercarl.com)