📜  门| GATE-CS-2015(模拟测试)|问题 4(1)

📅  最后修改于: 2023-12-03 15:42:18.118000             🧑  作者: Mango

问题 4

题目描述

假设有一个由整数组成的数组 $A$,其长度为 $n$。现在需要用单链表的方式存储 $A$ 中的元素,并进行如下操作:

  • 在链表尾插入一个元素 $x$
  • 删除链表中值为 $x$ 的第一个元素
  • 查找链表中值为 $x$ 的第一个元素

设计并实现一个算法,使上述操作的时间复杂度均为 $O(1)$。

算法设计

借助一个辅助哈希表,可以实现 $O(1)$ 时间复杂度的插入、删除和查找操作。

具体算法流程如下:

  1. 初始化一个空链表和一个空哈希表 $H$。
  2. 对于数组 $A$ 的每个元素 $a_i$,进行如下操作:
    1. 创建一个新节点 $node_i$,并将其值设为 $a_i$。
    2. 将 $node_i$ 插入到链表尾部。
    3. 在哈希表 $H$ 中将 $a_i$ 映射到节点 $node_i$ 上。
  3. 构造一个结构体 $List$,包含两个指针:$head$ 和 $tail$ 分别指向链表头和尾。
  4. 定义如下三个操作:
    1. 插入操作:新建一个节点 $node$,将其值设为 $x$,并将其插入到链表尾部。在哈希表 $H$ 中将 $x$ 映射到 $node$ 上。
    2. 删除操作:在哈希表 $H$ 中查找值为 $x$ 的节点 $node$,并将 $node$ 从链表中删除。
    3. 查找操作:在哈希表 $H$ 中查找值为 $x$ 的节点 $node$,并返回 $node$。
算法分析

该算法的时间复杂度为 $O(n)$,因为需要遍历整个数组 $A$ 来创建链表和哈希表。

但是,在执行操作时,由于哈希表的存在,插入、删除和查找都只需要在 $O(1)$ 的时间内完成。

因此,操作的总时间复杂度为 $O(1)$。

代码实现
#include <iostream>
#include <unordered_map>

using namespace std;

struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x) , next(nullptr) {}
};

class List {
public:
    ListNode* head;
    ListNode* tail;
    unordered_map<int, ListNode*> Hash;

    List() {
        head = tail = nullptr;
    }

    void insert(int x) {
        ListNode* node = new ListNode(x);
        if (tail == nullptr) {
            head = tail = node;
        } else {
            tail->next = node;
            tail = node;
        }
        Hash[x] = node;
    }

    void remove(int x) {
        auto it = Hash.find(x);
        if (it != Hash.end()) {
            ListNode* node = it->second;
            if (head == node) {
                head = head->next;
            } else {
                ListNode* cur = head;
                while (cur->next != node) {
                    cur = cur->next;
                }
                cur->next = node->next;
            }
            if (tail == node) {
                tail = tail->next;
            }
            Hash.erase(x);
            delete node;
        }
    }

    ListNode* search(int x) {
        auto it = Hash.find(x);
        if (it != Hash.end()) {
            return it->second;
        }
        return nullptr;
    }
};

int main() {
    int A[] = {1, 3, 4, 6, 7, 8};
    int n = sizeof(A) / sizeof(int);

    List list;
    for (int i = 0; i < n; i++) {
        list.insert(A[i]);
    }

    list.insert(5);
    list.remove(4);
    auto node = list.search(6);
    if (node != nullptr) {
        cout << node->val << endl;
    } else {
        cout << "not found" << endl;
    }

    return 0;
}

该代码实现采用 C++ 编程语言,使用了 STL 的 unordered_map 来实现哈希表。