【一看就会一写就废 指间算法】设计数字容器系统 —— 设计、哈希表、优先队列(懒删除堆)

32 阅读1分钟

指尖划过的轨迹,藏着最细腻的答案~

题目:

设计一个数字容器系统。

实现 NumberContainers 类:

  • NumberContainers() 初始化数字容器系统。
  • void change(int index, int number) 将下标 index 处的值设为 number 。当 index 已经被占用时,新值会替换原有的值。
  • int find(int number) 返回第一次出现 number 的下标。如果 number 不存在,则返回 -1

示例 1:

输入
["NumberContainers", "change", "change", "find", "change", "find"]
[[], [1, 10], [2, 10], [10], [1, 20], [10]]
输出
[null, null, null, 1, null, 2]

解释
NumberContainers numberContainers = new NumberContainers();
numberContainers.change(1, 10); // 将下标 1 处的值设为 10 。
numberContainers.change(2, 10); // 将下标 2 处的值设为 10 。
numberContainers.find(10);    // 返回 1 ,因为 10 第一次出现在下标 1 处。
numberContainers.change(1, 20); // 将下标 1 处的值设为 20 。
numberContainers.find(10);    // 返回 2 ,因为 10 现在第一次出现在下标 2 处。

提示:

  • 1 <= index, number <= 109
  • 最多调用 changefind 方法 105

分析:

我们使用两个哈希表,一个哈希表存储索引对应的值 index_to_number,另一个哈希表存储值对应的索引的从小到大排序的优先队列number_to_indices

具体实现时,在写入时(change)我们不需要删除数据,而在读取时(find)删除,如果队列顶的number不等于 index_to_number中存储的number说明是旧的需要删除的数据,直到队列为空或找到相等的number

AC代码:

class NumberContainers {
    unordered_map<int, int> `
index_to_number`;
    unordered_map<int, priority_queue<int, vector<int>, greater<int>>> number_to_indices;

public:
    void change(int index, int number) {
        index_to_number[index] = number;
        number_to_indices[number].push(index);
    }

    int find(int number) {
        auto& indices = number_to_indices[number];
        while(!indices.empty() && index_to_number[indices.top()] != number) {
            indices.pop();
        }

        return indices.empty() ? -1 : indices.top();
    }
};