数据结构设计
| #include <vector> |
| #include <iostream> |
| #include <algorithm> |
| #include <unordered_map> |
| |
| using namespace std; |
| |
| |
| unordered_map<int, pair<int, int>> map; |
| int setAllVal; |
| int setAllTime = -1; |
| |
| int timeStamp = 0; |
| |
| void put(int k, int v) { |
| if (map.find(k) == map.end()) { |
| |
| map.emplace(k, make_pair(v, timeStamp++)); |
| } else { |
| |
| map[k].first = v; |
| map[k].second = timeStamp++; |
| } |
| } |
| |
| void get(int k) { |
| |
| if (map.find(k) == map.end()) { |
| cout << -1 << endl; |
| return; |
| } |
| |
| if (map[k].second > setAllTime) |
| cout << map[k].first << endl; |
| else |
| cout << setAllVal << endl; |
| } |
| |
| void setAll(int v) { |
| setAllVal = v; |
| setAllTime = timeStamp++; |
| } |
| |
| int main() { |
| int n; |
| scanf("%d", &n); |
| for (int i = 0, opt, k, v; i < n; ++i) { |
| cin >> opt; |
| switch (opt) { |
| case 1: |
| scanf("%d%d", &k, &v); |
| put(k, v); |
| break; |
| case 2: |
| scanf("%d", &k); |
| get(k); |
| break; |
| case 3: |
| scanf("%d", &v); |
| setAll(v); |
| break; |
| } |
| } |
| } |
| #include <vector> |
| #include <iostream> |
| #include <algorithm> |
| #include <unordered_map> |
| |
| using namespace std; |
| |
| class LRUCache { |
| public: |
| |
| struct ListNode { |
| int key; |
| int value; |
| ListNode *prev; |
| ListNode *next; |
| |
| ListNode() { |
| prev = nullptr; |
| next = nullptr; |
| } |
| |
| ListNode(int k, int v) { |
| key = k; |
| value = v; |
| prev = nullptr; |
| next = nullptr; |
| } |
| }; |
| |
| |
| unordered_map<int, ListNode *> map; |
| |
| ListNode *dummyHead; |
| ListNode *dummyTail; |
| int capacity; |
| int size; |
| |
| LRUCache(int capacity) { |
| LRUCache::capacity = capacity; |
| size = 0; |
| dummyHead = new ListNode(); |
| dummyTail = new ListNode(); |
| dummyHead->next = dummyTail; |
| dummyTail->prev = dummyHead; |
| } |
| |
| |
| void addToTail(ListNode *node) { |
| node->next = dummyTail; |
| node->prev = dummyTail->prev; |
| dummyTail->prev->next = node; |
| dummyTail->prev = node; |
| } |
| |
| |
| |
| void moveToTail(ListNode *node) { |
| |
| node->prev->next = node->next; |
| node->next->prev = node->prev; |
| addToTail(node); |
| } |
| |
| |
| void removeHead() { |
| ListNode *node = dummyHead->next; |
| dummyHead->next->next->prev = dummyHead; |
| dummyHead->next = dummyHead->next->next; |
| delete node; |
| node = nullptr; |
| } |
| |
| int get(int key) { |
| |
| if (map.find(key) == map.end()) return -1; |
| |
| moveToTail(map[key]); |
| return map[key]->value; |
| } |
| |
| void put(int key, int value) { |
| if (map.find(key) == map.end()) { |
| |
| if (++size > capacity) { |
| map.erase(dummyHead->next->key); |
| removeHead(); |
| } |
| |
| ListNode *node = new ListNode(key, value); |
| addToTail(node); |
| map.emplace(key, node); |
| } else { |
| |
| map[key]->value = value; |
| moveToTail(map[key]); |
| } |
| } |
| }; |
- 用 map 定位元素在动态数组中的位置,删除时,转化成删除末尾元素,不让动态数组中有空位
| #include <vector> |
| #include <iostream> |
| #include <algorithm> |
| #include <unordered_map> |
| |
| using namespace std; |
| |
| class RandomizedSet { |
| public: |
| vector<int> arr; |
| |
| unordered_map<int, int> map; |
| |
| RandomizedSet() { |
| |
| } |
| |
| bool insert(int val) { |
| if (map.find(val) != map.end()) return false; |
| arr.emplace_back(val); |
| |
| map.emplace(val, arr.size() - 1); |
| return true; |
| } |
| |
| bool remove(int val) { |
| if (map.find(val) == map.end()) return false; |
| |
| map[arr[arr.size() - 1]] = map[val]; |
| |
| swap(arr[arr.size() - 1], arr[map[val]]); |
| arr.pop_back(); |
| map.erase(val); |
| return true; |
| } |
| |
| int getRandom() { |
| return arr[rand() % arr.size()]; |
| } |
| }; |
| #include <vector> |
| #include <iostream> |
| #include <algorithm> |
| #include <unordered_map> |
| #include <unordered_set> |
| |
| using namespace std; |
| |
| class RandomizedCollection { |
| public: |
| vector<int> arr; |
| |
| unordered_map<int, unordered_set<int>> map; |
| |
| RandomizedCollection() { |
| } |
| |
| bool insert(int val) { |
| arr.emplace_back(val); |
| |
| map[val].emplace(arr.size() - 1); |
| return map[val].size() == 1; |
| } |
| |
| bool remove(int val) { |
| if (map.find(val) == map.end()) return false; |
| if (val == arr[arr.size() - 1]) { |
| map[val].erase(arr.size() - 1); |
| arr.pop_back(); |
| } else { |
| |
| int valIndex = *map[val].begin(); |
| |
| int lastIndex = arr.size() - 1; |
| int last = arr[lastIndex]; |
| |
| |
| |
| map[val].erase(valIndex); |
| map[val].emplace(lastIndex); |
| |
| map[last].erase(lastIndex); |
| map[last].emplace(valIndex); |
| |
| |
| swap(arr[valIndex], arr[lastIndex]); |
| map[val].erase(lastIndex); |
| arr.pop_back(); |
| } |
| |
| if (map[val].size() == 0) map.erase(val); |
| return true; |
| } |
| |
| int getRandom() { |
| return arr[rand() % arr.size()]; |
| } |
| }; |
| #include <vector> |
| #include <iostream> |
| #include <algorithm> |
| #include <queue> |
| |
| |
| using namespace std; |
| |
| class MedianFinder { |
| public: |
| |
| priority_queue<int, vector<int>, less<int>> maxHeap; |
| |
| priority_queue<int, vector<int>, greater<int>> minHeap; |
| |
| MedianFinder() { |
| |
| } |
| |
| void addNum(int num) { |
| if (maxHeap.size() == 0) { |
| maxHeap.emplace(num); |
| return; |
| } |
| if ((maxHeap.size() + minHeap.size()) & 1) { |
| |
| if (num <= maxHeap.top()) { |
| |
| maxHeap.emplace(num); |
| |
| minHeap.emplace(maxHeap.top()); |
| maxHeap.pop(); |
| } else { |
| |
| minHeap.emplace(num); |
| } |
| } else { |
| |
| if (num <= maxHeap.top()) { |
| |
| maxHeap.emplace(num); |
| } else { |
| |
| minHeap.emplace(num); |
| |
| maxHeap.emplace(minHeap.top()); |
| minHeap.pop(); |
| } |
| } |
| } |
| |
| double findMedian() { |
| if ((maxHeap.size() + minHeap.size()) & 1) { |
| |
| return maxHeap.top(); |
| } else { |
| |
| return (maxHeap.top() + minHeap.top()) / 2.0; |
| } |
| } |
| }; |
| #include <vector> |
| #include <iostream> |
| #include <algorithm> |
| #include <queue> |
| #include <stack> |
| #include <unordered_map> |
| |
| using namespace std; |
| |
| class FreqStack { |
| public: |
| |
| unordered_map<int, int> freq; |
| |
| unordered_map<int, vector<int>> countValues; |
| |
| int _max; |
| |
| FreqStack() { |
| |
| } |
| |
| void push(int val) { |
| freq[val]++; |
| |
| if (countValues.find(freq[val]) == countValues.end()) |
| countValues.emplace(freq[val], vector<int>()); |
| |
| countValues[freq[val]].emplace_back(val); |
| |
| _max = max(_max, freq[val]); |
| } |
| |
| int pop() { |
| |
| int res = countValues[_max].back(); |
| countValues[_max].pop_back(); |
| |
| if (countValues[_max].empty()) |
| countValues.erase(_max--); |
| |
| if (freq[res] == 1) |
| freq.erase(res); |
| else |
| freq[res]--; |
| return res; |
| } |
| }; |
| #include <vector> |
| #include <iostream> |
| #include <algorithm> |
| #include <queue> |
| #include <stack> |
| #include <string> |
| #include <unordered_map> |
| #include <unordered_set> |
| |
| using namespace std; |
| |
| class AllOne { |
| public: |
| |
| struct ListNode { |
| int times; |
| unordered_set<string> bucket; |
| ListNode *prev; |
| ListNode *next; |
| |
| ListNode() { |
| prev = nullptr; |
| next = nullptr; |
| } |
| |
| ListNode(int times, string key) : ListNode() { |
| this->times = times; |
| bucket.emplace(key); |
| } |
| }; |
| |
| |
| unordered_map<string, ListNode *> map; |
| ListNode *dummyHead; |
| ListNode *dummyTail; |
| |
| |
| void insertNode(ListNode *pos, ListNode *node) { |
| node->prev = pos; |
| node->next = pos->next; |
| pos->next->prev = node; |
| pos->next = node; |
| } |
| |
| void removeNode(ListNode *node) { |
| node->next->prev = node->prev; |
| node->prev->next = node->next; |
| delete node; |
| node = nullptr; |
| } |
| |
| AllOne() { |
| dummyHead = new ListNode(); |
| dummyTail = new ListNode(); |
| dummyHead->next = dummyTail; |
| dummyTail->prev = dummyHead; |
| dummyHead->times = 0; |
| dummyTail->times = INT_MAX; |
| } |
| |
| void inc(string key) { |
| if (map.find(key) == map.end()) { |
| |
| if (dummyHead->next->times == 1) { |
| |
| dummyHead->next->bucket.emplace(key); |
| map[key] = dummyHead->next; |
| } else { |
| |
| ListNode *node = new ListNode(1, key); |
| map[key] = node; |
| insertNode(dummyHead, node); |
| } |
| } else { |
| |
| ListNode *cur = map[key]; |
| if (cur->next->times == cur->times + 1) { |
| |
| cur->next->bucket.emplace(key); |
| map[key] = cur->next; |
| } else { |
| |
| ListNode *node = new ListNode(cur->times + 1, key); |
| map[key] = node; |
| insertNode(cur, node); |
| } |
| |
| cur->bucket.erase(key); |
| if (cur->bucket.empty()) removeNode(cur); |
| } |
| } |
| |
| void dec(string key) { |
| ListNode *cur = map[key]; |
| if (cur->times == 1) { |
| map.erase(key); |
| } else { |
| if (cur->prev->times == cur->times - 1) { |
| |
| cur->prev->bucket.emplace(key); |
| map[key] = cur->prev; |
| } else { |
| |
| ListNode *node = new ListNode(cur->times - 1, key); |
| map[key] = node; |
| insertNode(cur->prev, node); |
| } |
| } |
| |
| cur->bucket.erase(key); |
| if (cur->bucket.empty()) removeNode(cur); |
| } |
| |
| string getMaxKey() { |
| if (dummyTail->prev == dummyHead) return ""; |
| return *(dummyTail->prev->bucket.begin()); |
| } |
| |
| string getMinKey() { |
| if (dummyHead->next == dummyTail) return ""; |
| return *(dummyHead->next->bucket.begin()); |
| } |
| }; |
| |
本文作者:n1ce2cv
本文链接:https://www.cnblogs.com/sprinining/p/18438260
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2021-09-28 锁的分类
2021-09-28 synchronized锁的内容
2021-09-28 ReentrantLock
2021-09-28 虚假唤醒