要求解两个递增链表的交集并存放在第一个链表中,可以通过以下步骤实现:
以下是利用哈希表实现这一算法的C++代码示例:
#include <iostream>
#include <unordered_set>
// 定义单链表的节点结构
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
// 用于打印链表的辅助函数
void printList(ListNode* head) {
while (head != nullptr) {
std::cout << head->val << " ";
head = head->next;
}
std::cout << std::endl;
}
// 求两个升序链表的交集存放在第一个链表中
ListNode* getIntersection(ListNode* headA, ListNode* headB) {
std::unordered_set<int> setB; // 用于存储链表B中的元素的哈希表
ListNode dummy(0); // 创建一个哑节点头,方便插入操作
ListNode* tail = &dummy; // 尾指针,指向最后一个有效节点
// 用链表B的元素填充哈希表
while (headB != nullptr) {
setB.insert(headB->val);
headB = headB->next;
}
// 遍历链表A,查找交集,并添加到新的链表中
while (headA != nullptr) {
if (setB.find(headA->val) != setB.end()) { // 如果头节点存在于集合B中
tail->next = new ListNode(headA->val); // 把元素添加到新链表中
tail = tail->next; // 移动尾指针
setB.erase(headA->val); // 从集合B中移除该元素,避免重复添加
}
headA = headA->next;
}
// 删除原来链表A上不属于交集的元素
ListNode* head = dummy.next;
ListNode* cur = headA;
while (cur != nullptr && cur->next != nullptr) {
if (setB.find(cur->next->val) == setB.end()) { // 如果下一个节点不在集合B中
ListNode* temp = cur->next;
cur->next = cur->next->next;
delete temp; // 删除该节点
} else {
cur = cur->next;
}
}
return head; // 返回哑节点的下一个节点为新链表头
}
int main() {
// 示例:创建两个链表并进行求交集
ListNode* l1 = new ListNode(1);
l1->next = new ListNode(2);
l1->next->next = new ListNode(3);
l1->next->next->next = new ListNode(4);
ListNode* l2 = new ListNode(2);
l2->next = new ListNode(3);
l2->next->next = new ListNode(6);
std::cout << "List A: ";
printList(l1);
std::cout << "List B: ";
printList(l2);
ListNode* intersection = getIntersection(l1, l2);
std::cout << "Intersection List A: ";
printList(intersection);
// 记得释放链表内存,避免内存泄露
while (intersection != nullptr) {
ListNode* temp = intersection;
intersection = intersection->next;
delete temp;
}
return 0;
}
这段代码将输出结果放在A链表中,所以不需要另外分配空间;只需要删除原本不属于交集的部分。我们先通过一个哑节点 dummy
构造一个新的链表来放交集元素,然后遍历A链表,删除那些不在B中的元素。