• 智能AI问答!更聪明、更完整、原创作!
  • 一款基于GPT的超级AI机器人,可以回答问题、聊天、创作、写文案!

已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出A 与B的交集,并存放于A链表中,用c++写算法

发布于 2024-11-28 22:36:35

要求解两个递增链表的交集并存放在第一个链表中,可以通过以下步骤实现:

  1. 遍历两个链表,同时记录它们的元素。
  2. 使用哈希表或其他数据结构存储一个链表的所有元素,用于快速查找。
  3. 遍历另一个链表,使用步骤2中的结构检查是否是两个集合的公共元素。
  4. 如果是公共元素,添加到第一个链表的结果中。

以下是利用哈希表实现这一算法的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中的元素。

0 条评论

发布
问题

在线
客服