diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/solution.md" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/solution.md" index 81a15b30138db54c3d6e59cfcc970db3d66b8b5f..202817893aeb8f1eb2bfd96a03877a0ded025cda 100644 --- "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/solution.md" +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/solution.md" @@ -56,7 +56,8 @@ lRUCache.get(4); // 返回 4 ## aop ### before ```cpp - +#include +using namespace std; ``` ### after ```cpp @@ -65,21 +66,249 @@ lRUCache.get(4); // 返回 4 ## 答案 ```cpp +class LRUCache +{ +public: + LRUCache(int capacity) : cap(capacity) {} + + int get(int key) + { + if (m.count(key) != 0) + { + int val = m[key]->second; + l.erase(m[key]); + l.push_front({key, val}); + m[key] = l.begin(); + return val; + } + return -1; + } + + void put(int key, int value) + { + if (m.count(key) != 0) + { + l.erase(m[key]); + l.push_front({key, value}); + m[key] = l.begin(); + } + else + { + m.erase(l.back().first); + l.pop_back(); + l.push_front({key, value}); + m[key] = l.begin(); + } + } +private: + int cap; + list> l; + unordered_map>::iterator> m; +}; ``` ## 选项 ### A ```cpp +class LRUCache +{ +private: + unordered_map cache; + DLinkedNode *head; + DLinkedNode *tail; + int size; + int capacity; + +public: + LRUCache(int _capacity) : capacity(_capacity), size(0) + { + + head = new DLinkedNode(); + tail = new DLinkedNode(); + head->next = tail; + tail->prev = head; + } + + int get(int key) + { + if (!cache.count(key)) + { + return -1; + } + + DLinkedNode *node = cache[key]; + moveToHead(node); + return node->value; + } + + void put(int key, int value) + { + if (!cache.count(key)) + { + + DLinkedNode *node = new DLinkedNode(key, value); + + cache[key] = node; + + addToHead(node); + ++size; + if (size > capacity) + { + + DLinkedNode *removed = removeTail(); + cache.erase(removed->key); + + delete removed; + --size; + } + } + else + { + + DLinkedNode *node = cache[key]; + node->value = value; + moveToHead(node); + } + } + + void addToHead(DLinkedNode *node) + { + node->prev = head; + node->next = head->next; + head->next->prev = node; + head->next = node; + } + + void removeNode(DLinkedNode *node) + { + node->prev->next = node->next; + + node->next->prev = node->prev; + } + + void moveToHead(DLinkedNode *node) + { + removeNode(node); + addToHead(node); + } + + DLinkedNode *removeTail() + { + DLinkedNode *node = tail->prev; + removeNode(node); + return node; + } +}; ``` ### B ```cpp +class LRUCache +{ +private: + int capacity; + list> cl; + unordered_map>::iterator> cm; + +public: + LRUCache(int capacity) + { + this->capacity = capacity; + } + + int get(int key) + { + auto it = cm.find(key); + if (it != cm.end()) + { + pair p = *cm[key]; + int value = p.second; + cl.erase(cm[key]); + cl.push_front(p); + cm[key] = cl.begin(); + return value; + } + else + return -1; + } + void put(int key, int value) + { + auto it = cm.find(key); + if (it != cm.end()) + { + cl.erase(cm[key]); + cl.push_front({key, value}); + cm[key] = cl.begin(); + } + else + { + if (cl.size() == capacity) + { + int old_key = cl.back().first; + cl.pop_back(); + cm.erase(old_key); + } + cl.push_front({key, value}); + cm.insert({key, cl.begin()}); + } + } +}; ``` ### C ```cpp +class LRUCache +{ +private: + int capacity, size; + list cl; + unordered_map cm; + +public: + LRUCache(int capacity) + { + this->capacity = capacity; + size = 0; + } + + int get(int key) + { + auto it = cm.find(key); + if (it != cm.end()) + { + cl.remove(key); + cl.push_back(key); + return it->second; + } + else + return -1; + } + void put(int key, int value) + { + auto it = cm.find(key); + if (it != cm.end()) + { + it->second = value; + cl.remove(key); + cl.push_back(key); + } + else + { + if (size == capacity) + { + int old_key = cl.front(); + cl.pop_front(); + cm.erase(old_key); + size--; + } + cl.push_back(key); + cm.insert({key, value}); + size++; + } + } +}; ``` diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.cpp" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.cpp" index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..099130411ef5cac9fa9f05dbad4e4bc26315c7cb 100644 --- "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.cpp" +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.cpp" @@ -0,0 +1,22 @@ +#include +using namespace std; + +class Solution +{ +public: + bool isIsomorphic(string s, string t) + { + unordered_map map1; + unordered_map map2; + int n = s.size(); + for (int i = 0; i < n; i++) + { + char x = s[i], y = t[i]; + if ((map1.count(x) && map1[x] != y) || (map2.count(y) && map2[y] != x)) + return false; + map1[x] = y; + map2[y] = x; + } + return true; + } +}; \ No newline at end of file diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.md" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.md" index ac6fc93491e6777c906147b30243caf6540bc5e8..558af15fee4a1167d06c91acf34d1a2ed2b75fac 100644 --- "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.md" +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.md" @@ -38,30 +38,155 @@ ## aop ### before ```cpp - +#include +using namespace std; ``` ### after ```cpp - +int main() +{ + Solution sol; + string a = "egg"; + string b = "add"; + + bool res; + + res = sol.isIsomorphic(a, b); + cout << res; + return 0; +} ``` ## 答案 ```cpp - +class Solution +{ +public: + bool isIsomorphic(string s, string t) + { + if (s.size() != t.size()) + return false; + for (int i = 0; i < s.size(); i++) + { + int pos = s.find_first_of(s[i], i + 1); + while (pos != -1) + { + if (t[i] == t[pos + 1]) + { + s.erase(pos, 1); + t.erase(pos, 1); + pos = s.find_first_of(s[i], pos + 1); + } + else + return false; + } + } + for (int i = 0; i < t.size(); i++) + { + int pos = t.find_first_of(t[i], i + 1); + while (pos != -1) + { + if (s[i] == s[pos + 1]) + { + s.erase(pos, 1); + t.erase(pos, 1); + pos = t.find_first_of(t[i], pos + 1); + } + else + return false; + } + } + return true; + } +}; ``` ## 选项 ### A ```cpp - +class Solution +{ +public: + bool isIsomorphic(string s, string t) + { + if (s.size() != t.size()) + return false; + for (int i = 0; i < s.size(); i++) + { + if (s.find(s[i]) != t.find(t[i])) + return false; + } + return true; + } +}; ``` ### B ```cpp - +class Solution +{ +public: + bool isIsomorphic(string s, string t) + { + if (s.size() != t.size()) + return false; + for (int i = 0; i < s.size(); i++) + { + if (s[i] == s[i + 1]) + { + s.erase(i + 1, 1); + i--; + } + } + for (int i = 0; i < t.size(); i++) + { + if (t[i] == t[i + 1]) + { + t.erase(i + 1, 1); + i--; + } + } + if (s.size() != t.size()) + return false; + for (int i = 0; i < s.size(); i++) + { + int pos = s.find_first_of(s[i], i + 1); + while (pos != -1) + { + if (t[i] == t[pos]) + { + s.erase(pos, 1); + t.erase(pos, 1); + pos = s.find_first_of(s[i], pos + 1); + } + else + return false; + } + } + return true; + } +}; ``` ### C ```cpp - +class Solution +{ +public: + bool isIsomorphic(string s, string t) + { + unordered_map map1; + unordered_map map2; + int n = s.size(); + for (int i = 0; i < n; i++) + { + char x = s[i], y = t[i]; + if ((map1.count(x) && map1[x] != y) || (map2.count(y) && map2[y] != x)) + return false; + map1[x] = y; + map2[y] = x; + } + return true; + } +}; ``` diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.cpp" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.cpp" index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d471cd99a661cd41b3cb74004f263d2ddacb3905 100644 --- "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.cpp" +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.cpp" @@ -0,0 +1,62 @@ +#include +using namespace std; + +class Twitter +{ +public: + /** Initialize your data structure here. */ + Twitter() + { + } + + /** Compose a new tweet. */ + void postTweet(int userId, int tweetId) + { + context.push_back(make_pair(userId, tweetId)); + } + + /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */ + vector getNewsFeed(int userId) + { + int n = context.size(); + int count = 0; + vector res; + int k = n - 1; + while (count < 10 && k >= 0) + { + auto it = context[k]; + if (it.first == userId || tmp[make_pair(userId, it.first)]) + { + res.push_back(context[k].second); + count++; + } + k--; + } + return res; + } + + /** Follower follows a followee. If the operation is invalid, it should be a no-op. */ + void follow(int followerId, int followeeId) + { + tmp[make_pair(followerId, followeeId)] = 1; + } + + /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ + void unfollow(int followerId, int followeeId) + { + tmp[make_pair(followerId, followeeId)] = 0; + } + +private: + map, int> tmp; + vector> context; +}; + +/** + * Your Twitter object will be instantiated and called as such: + * Twitter* obj = new Twitter(); + * obj->postTweet(userId,tweetId); + * vector param_2 = obj->getNewsFeed(userId); + * obj->follow(followerId,followeeId); + * obj->unfollow(followerId,followeeId); + */ diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.md" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.md" index 3b4b30a480e038bb40244cbe014f0f5bfdf7e5d3..5c8f5ba370d32de1acc89cf9e31b54a7f762b571 100644 --- "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.md" +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.md" @@ -47,7 +47,8 @@ twitter.getNewsFeed(1); // 用户 1 获取推文应当返回一个列表,其 ## aop ### before ```cpp - +#include +using namespace std; ``` ### after ```cpp @@ -56,21 +57,294 @@ twitter.getNewsFeed(1); // 用户 1 获取推文应当返回一个列表,其 ## 答案 ```cpp +class Twitter +{ +public: + /** Initialize your data structure here. */ + Twitter() + { + } + + /** Compose a new tweet. */ + void postTweet(int userId, int tweetId) + { + tweets[userId].push_back(make_pair(time++, tweetId)); + } + + /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */ + vector getNewsFeed(int userId) + { + vector userIds({userId}); + if (following.find(userId) != following.end()) + { + userIds.insert(userIds.begin(), following[userId].begin(), following[userId].end()); + } + + vector index(userIds.size()); + for (int i = 0; i < userIds.size(); ++i) + { + index[i] = tweets[userIds[i]].size(); + } + + vector res; + while (res.size() < 10) + { + int mxi = 0, mxtime = INT_MIN, mxTweet = 0; + for (int i = 0; i < index.size(); ++i) + { + int idx = index[i]; + if (idx > 0) + { + int ui = userIds[i]; + int time = tweets[ui][idx].first; + if (time > mxtime) + { + mxi = i; + mxtime = time; + mxTweet = tweets[ui][idx].second; + } + } + } + + if (mxtime == INT_MIN) + { + break; + } + + ++index[mxi]; + res.push_back(mxTweet); + } + + return res; + } + + /** Follower follows a followee. If the operation is invalid, it should be a no-op. */ + void follow(int followerId, int followeeId) + { + if (followerId != followeeId) + { + following[followerId].insert(followeeId); + } + } + + /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ + void unfollow(int followerId, int followeeId) + { + if (following.find(followerId) == following.end()) + { + return; + } + following[followerId].erase(followeeId); + if (following[followerId].empty()) + { + following.erase(followerId); + } + } + +private: + int time{0}; + unordered_map> following; + unordered_map>> tweets; +}; +/** + * Your Twitter object will be instantiated and called as such: + * Twitter obj = new Twitter(); + * obj.postTweet(userId,tweetId); + * vector param_2 = obj.getNewsFeed(userId); + * obj.follow(followerId,followeeId); + * obj.unfollow(followerId,followeeId); + */ ``` ## 选项 ### A ```cpp +class Twitter +{ +private: + list> twitterNews; + map> followMap; + +public: + /** Initialize your data structure here. */ + Twitter() + { + } + + /** Compose a new tweet. */ + void postTweet(int userId, int tweetId) + { + + twitterNews.insert(twitterNews.begin(), pair(userId, tweetId)); + } + + /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */ + vector getNewsFeed(int userId) + { + vector result; + list>::iterator it = twitterNews.begin(); + + while (it != twitterNews.end() && result.size() < 10) + { + + if (it->first == userId || followMap[userId][it->first]) + { + result.push_back(it->second); + } + it++; + } + return result; + } + + /** Follower follows a followee. If the operation is invalid, it should be a no-op. */ + void follow(int followerId, int followeeId) + { + followMap[followerId][followeeId] = true; + } + + /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ + void unfollow(int followerId, int followeeId) + { + followMap[followerId][followeeId] = false; + } +}; + +/** + * Your Twitter object will be instantiated and called as such: + * Twitter obj = new Twitter(); + * obj.postTweet(userId,tweetId); + * vector param_2 = obj.getNewsFeed(userId); + * obj.follow(followerId,followeeId); + * obj.unfollow(followerId,followeeId); + */ ``` ### B ```cpp +class Twitter +{ +public: + /** Initialize your data structure here. */ + Twitter() + { + } + + /** Compose a new tweet. */ + void postTweet(int userId, int tweetId) + { + context.push_back(make_pair(userId, tweetId)); + } + + /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */ + vector getNewsFeed(int userId) + { + int n = context.size(); + int count = 0; + vector res; + int k = n - 1; + while (count < 10 && k >= 0) + { + auto it = context[k]; + if (it.first == userId || tmp[make_pair(userId, it.first)]) + { + res.push_back(context[k].second); + count++; + } + k--; + } + return res; + } + + /** Follower follows a followee. If the operation is invalid, it should be a no-op. */ + void follow(int followerId, int followeeId) + { + tmp[make_pair(followerId, followeeId)] = 1; + } + + /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ + void unfollow(int followerId, int followeeId) + { + tmp[make_pair(followerId, followeeId)] = 0; + } + +private: + map, int> tmp; + vector> context; +}; + +/** + * Your Twitter object will be instantiated and called as such: + * Twitter* obj = new Twitter(); + * obj->postTweet(userId,tweetId); + * vector param_2 = obj->getNewsFeed(userId); + * obj->follow(followerId,followeeId); + * obj->unfollow(followerId,followeeId); + */ ``` ### C ```cpp +class Twitter +{ +public: + /** Initialize your data structure here. */ + Twitter() + { + } + + /** Compose a new tweet. */ + void postTweet(int userId, int tweetId) + { + context.push_back(make_pair(userId, tweetId)); + } + + /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */ + vector getNewsFeed(int userId) + { + int n = context.size(); + int count = 0; + vector res; + int k = n - 1; + while (count < 10 && k >= 0) + { + auto it = context[k]; + if (it.first == userId || tmp[make_pair(userId, it.first)]) + { + res.push_back(context[k].second); + count++; + } + k--; + } + return res; + } + + /** Follower follows a followee. If the operation is invalid, it should be a no-op. */ + void follow(int followerId, int followeeId) + { + tmp[make_pair(followerId, followeeId)] = 1; + } + + /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ + void unfollow(int followerId, int followeeId) + { + tmp[make_pair(followerId, followeeId)] = 0; + } + +private: + map, int> tmp; + vector> context; +}; + +/** + * Your Twitter object will be instantiated and called as such: + * Twitter* obj = new Twitter(); + * obj->postTweet(userId,tweetId); + * vector param_2 = obj->getNewsFeed(userId); + * obj->follow(followerId,followeeId); + * obj->unfollow(followerId,followeeId); + */ ``` diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.cpp" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.cpp" index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6051691a755fc6d23bf9d956ed183591dff67fe3 100644 --- "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.cpp" +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.cpp" @@ -0,0 +1,47 @@ +#include +using namespace std; + +class RandomizedSet +{ +public: + vector nums; + unordered_map nums_inds; + /** Initialize your data structure here. */ + RandomizedSet() + { + } + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + bool insert(int val) + { + if (nums_inds.count(val) != 0) + return false; + nums.push_back(val); + nums_inds[val] = nums.size() - 1; + return true; + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + bool remove(int val) + { + if (nums_inds.count(val) == 0) + return false; + + int last = nums.back(); + int ind = nums_inds[val]; + + nums[ind] = last; + nums_inds[last] = ind; + + nums.pop_back(); + nums_inds.erase(val); + return true; + } + + /** Get a random element from the set. */ + int getRandom() + { + int ind = rand() % nums.size(); + return nums[ind]; + } +}; diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.md" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.md" index 2020ecc47f96b609f91e4a2de2bf702c15f7be37..50bb832bda98197e1dc7bd4294816296250705da 100644 --- "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.md" +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.md" @@ -50,6 +50,8 @@ randomizedSet.getRandom(); // 由于 2 是集合中唯一的数字,getRandom ## aop ### before ```cpp +#include +using namespace std; ``` ### after @@ -59,21 +61,193 @@ randomizedSet.getRandom(); // 由于 2 是集合中唯一的数字,getRandom ## 答案 ```cpp - +class RandomizedSet +{ + unordered_map dict; + vector list; + +public: + /** Initialize your data structure here. */ + RandomizedSet() + { + srand(time(0)); + } + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + bool insert(int val) + { + if (dict.find(val) != dict.end()) + return false; + list.push_back(val); + dict[val] = list.size(); + return true; + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + bool remove(int val) + { + if (dict.find(val) == dict.end()) + return false; + dict[list.back()] = dict[val]; + swap(list.back(), list[dict[val]]); + list.pop_back(); + dict.erase(val); + return true; + } + + /** Get a random element from the set. */ + int getRandom() + { + int pos = list.empty() ? 0 : rand() % list.size(); + return list[pos]; + } +}; ``` ## 选项 ### A ```cpp - +class RandomizedSet +{ +public: + /** Initialize your data structure here. */ + RandomizedSet() + { + } + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + bool insert(int val) + { + if (mMap.count(val) > 0) + return false; + + mData.push_back(val); + mMap[val] = mData.size() - 1; + return true; + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + bool remove(int val) + { + + if (mMap.count(val) > 0) + { + int last_num = mData.back(); + int val_index = mMap[val]; + mData[val_index] = last_num; + mMap[last_num] = val_index; + + mData.pop_back(); + mMap.erase(val); + + return true; + } + + return false; + } + + /** Get a random element from the set. */ + int getRandom() + { + int index = rand() % mData.size(); + return mData[index]; + } + +private: + vector mData; + unordered_map mMap; +}; ``` ### B ```cpp - +class RandomizedSet +{ +public: + unordered_set ust; + + /** Initialize your data structure here. */ + RandomizedSet() + { + } + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + bool insert(int val) + { + if (ust.find(val) != ust.end()) + return false; + ust.insert(val); + return true; + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + bool remove(int val) + { + if (ust.find(val) == ust.end()) + return false; + ust.erase(val); + return true; + } + + /** Get a random element from the set. */ + int getRandom() + { + int ind = rand() % ust.size(); + auto it = ust.begin(); + for (int i = 0; i < ind; i++) + { + it++; + } + return *it; + } +}; ``` ### C ```cpp +class RandomizedSet +{ +public: + vector nums; + unordered_map nums_inds; + /** Initialize your data structure here. */ + RandomizedSet() + { + } + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + bool insert(int val) + { + if (nums_inds.count(val) != 0) + return false; + nums.push_back(val); + nums_inds[val] = nums.size() - 1; + return true; + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + bool remove(int val) + { + if (nums_inds.count(val) == 0) + return false; + + int last = nums.back(); + int ind = nums_inds[val]; + + nums[ind] = last; + nums_inds[last] = ind; + + nums.pop_back(); + nums_inds.erase(val); + return true; + } + + /** Get a random element from the set. */ + int getRandom() + { + int ind = rand() % nums.size(); + return nums[ind]; + } +}; ``` diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.cpp" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.cpp" index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ae849919b82ddbcd0c49881c977f7e001cc48b28 100644 --- "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.cpp" +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.cpp" @@ -0,0 +1,60 @@ +#include +using namespace std; + +class RandomizedCollection +{ +public: + vector nums; + unordered_map> numsIndex; + int size; + /** Initialize your data structure here. */ + RandomizedCollection() + { + size = 0; + } + + /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ + bool insert(int val) + { + nums.push_back(val); + numsIndex[val].insert(size); + size++; + return numsIndex[val].size() == 1; + } + + /** Removes a value from the collection. Returns true if the collection contained the specified element. */ + bool remove(int val) + { + if (numsIndex.count(val) == 0) + return false; + int last = nums.back(); + int id = size - 1; + if (last != val) + { + id = *(numsIndex[val].begin()); + numsIndex[last].erase(size - 1); + numsIndex[last].insert(id); + nums[id] = last; + } + nums.pop_back(); + size--; + numsIndex[val].erase(id); + if (numsIndex[val].empty()) + numsIndex.erase(val); + return true; + } + + /** Get a random element from the collection. */ + int getRandom() + { + return nums[random() % size]; + } +}; + +/** + * Your RandomizedCollection object will be instantiated and called as such: + * RandomizedCollection* obj = new RandomizedCollection(); + * bool param_1 = obj->insert(val); + * bool param_2 = obj->remove(val); + * int param_3 = obj->getRandom(); + */ diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.md" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.md" index 0ea59156c2a5299778775e6bc5a7fb2f8a1d0dc1..d6bb395d839cfd55ea6c84c535c2c880b9c0d2e5 100644 --- "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.md" +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.md" @@ -37,7 +37,8 @@ collection.getRandom(); ## aop ### before ```cpp - +#include +using namespace std; ``` ### after ```cpp @@ -46,21 +47,220 @@ collection.getRandom(); ## 答案 ```cpp +class RandomizedCollection +{ +public: + /** Initialize your data structure here. */ + RandomizedCollection() + { + this->num = 0; + } + + /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ + bool insert(int val) + { + this->num++; + bool res; + if (this->M.find(val) == this->M.end() || this->M[val] == 0) + { + this->M[val] = 1; + res = true; + } + else + { + this->M[val]++; + res = false; + } + return res; + } + + /** Removes a value from the collection. Returns true if the collection contained the specified element. */ + bool remove(int val) + { + if (this->M.find(val) == this->M.end() || this->M[val] == 0) + { + return false; + } + else + { + M[val]--; + this->num--; + return true; + } + } + /** Get a random element from the collection. */ + int getRandom() + { + if (this->num > 0) + { + srand((unsigned)time(NULL)); + int randomValue = rand() % (this->num) + 1; + for (auto it : M) + { + randomValue -= it.second; + if (randomValue <= 0) + return it.first; + } + } + return 0; + } + +private: + unordered_map M; + int num; +}; ``` ## 选项 ### A ```cpp +class RandomizedSet +{ +public: + vector nums; + unordered_map numIndex; + int size; + /** Initialize your data structure here. */ + RandomizedSet() + { + size = 0; + } + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + bool insert(int val) + { + if (numIndex.count(val) == 1) + return false; + nums.push_back(val); + numIndex[val] = size; + size++; + return true; + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + bool remove(int val) + { + if (numIndex.count(val) == 0) + return false; + int last = nums.back(); + nums[numIndex[val]] = last; + numIndex[last] = numIndex[val]; + nums.pop_back(); + numIndex.erase(val); + size--; + return true; + } + /** Get a random element from the set. */ + int getRandom() + { + return nums[random() % size]; + } +}; ``` ### B ```cpp +class RandomizedCollection +{ +public: + unordered_map> idx; + vector nums; + /** Initialize your data structure here. */ + RandomizedCollection() + { + } + + /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ + bool insert(int val) + { + nums.push_back(val); + idx[val].insert(nums.size() - 1); + return idx[val].size() == 1; + } + + /** Removes a value from the collection. Returns true if the collection contained the specified element. */ + bool remove(int val) + { + if (idx.find(val) == idx.end()) + { + return false; + } + int i = *(idx[val].begin()); + nums[i] = nums.back(); + idx[val].erase(i); + idx[nums[i]].erase(nums.size() - 1); + if (i < nums.size() - 1) + { + idx[nums[i]].insert(i); + } + if (idx[val].size() == 0) + { + idx.erase(val); + } + nums.pop_back(); + return true; + } + + /** Get a random element from the collection. */ + int getRandom() + { + return nums[rand() % nums.size()]; + } +}; ``` ### C ```cpp +class RandomizedCollection +{ +public: + vector nums; + unordered_map> numsIndex; + int size; + /** Initialize your data structure here. */ + RandomizedCollection() + { + size = 0; + } + + /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ + bool insert(int val) + { + nums.push_back(val); + numsIndex[val].insert(size); + size++; + return numsIndex[val].size() == 1; + } + + /** Removes a value from the collection. Returns true if the collection contained the specified element. */ + bool remove(int val) + { + if (numsIndex.count(val) == 0) + return false; + int last = nums.back(); + int id = size - 1; + if (last != val) + { + id = *(numsIndex[val].begin()); + numsIndex[last].erase(size - 1); + numsIndex[last].insert(id); + nums[id] = last; + } + nums.pop_back(); + size--; + numsIndex[val].erase(id); + if (numsIndex[val].empty()) + numsIndex.erase(val); + return true; + } + /** Get a random element from the collection. */ + int getRandom() + { + return nums[random() % size]; + } +}; ``` diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/459_LFU \347\274\223\345\255\230/solution.cpp" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/459_LFU \347\274\223\345\255\230/solution.cpp" index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3d328bb5ecdc2f09e47273eeed57e60cd0ab4ba2 100644 --- "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/459_LFU \347\274\223\345\255\230/solution.cpp" +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/459_LFU \347\274\223\345\255\230/solution.cpp" @@ -0,0 +1,75 @@ +#include +using namespace std; + +struct Value +{ + Value(int count_, int time_, int key_, int value_) + : count(count_), + key(key_), + value(value_), + time(time_) {} + bool operator<(const Value &a) const + { + return count == a.count ? time < a.time : count < a.count; + } + int key; + int value; + int count; + int time; +}; +class LFUCache +{ +public: + LFUCache(int capacity_) + : capacity(capacity_), + time(0) {} + + int get(int key) + { + if (capacity == 0) + return -1; + auto it = table.find(key); + if (it == table.end()) + return -1; + Value cache = it->second; + judge.erase(cache); + cache.count++; + cache.time = ++time; + judge.insert(cache); + it->second = cache; + return cache.value; + } + + void put(int key, int value) + { + if (capacity == 0) + return; + auto it = table.find(key); + if (it == table.end()) + { + if (table.size() == capacity) + { + + table.erase(judge.begin()->key); + judge.erase(judge.begin()); + } + Value put_(0, ++time, key, value); + table.insert({key, put_}); + judge.insert(put_); + } + else + { + Value temp = it->second; + judge.erase(temp); + Value put_(++temp.count, ++time, key, value); + it->second = put_; + judge.insert(put_); + } + } + +private: + const int capacity; + int time; + unordered_map table; + set judge; +}; diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/459_LFU \347\274\223\345\255\230/solution.md" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/459_LFU \347\274\223\345\255\230/solution.md" index c8678a2dabe3f55ce318529e75fde4694ed5b176..ea06644c6f0a937c5ae90f63ef1a02b4eaf0c819 100644 --- "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/459_LFU \347\274\223\345\255\230/solution.md" +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/1.leetcode/459_LFU \347\274\223\345\255\230/solution.md" @@ -64,7 +64,8 @@ lFUCache.get(4); // 返回 4 ## aop ### before ```cpp - +#include +using namespace std; ``` ### after ```cpp @@ -73,21 +74,319 @@ lFUCache.get(4); // 返回 4 ## 答案 ```cpp +class LFUCache +{ +private: + int cap; + int size; + int minfre; + unordered_map> m; + unordered_map> hash_fre; + unordered_map::iterator> hash_node; + +public: + LFUCache(int capacity) : cap(capacity), size(0) {} + + int get(int key) + { + if (m.count(key) == 0) + return -1; + + hash_fre[m[key].second].erase(hash_node[key]); + m[key].second++; + hash_fre[m[key].second].push_back(key); + hash_node[key] = --hash_fre[m[key].second].end(); + if (hash_fre[minfre].size() == 0) + { + minfre++; + } + return m[key].first; + } + + void put(int key, int value) + { + if (cap <= 0) + return; + if (get(key) != -1) + { + m[key].first = value; + return; + } + if (size >= cap) + { + m.erase(hash_fre[minfre].front()); + hash_node.erase(hash_fre[minfre].front()); + hash_fre[minfre].pop_front(); + } + + m[key] = {value, 1}; + hash_fre[1].push_back(key); + hash_node[key] = hash_fre[1].end(); + minfre = 1; + if (size < cap) + size++; + } +}; ``` ## 选项 ### A ```cpp +class Node +{ +public: + int cnt; + int time; + int key; + int val; + Node(int cnt, int time, int key, int val) + { + this->cnt = cnt; + this->time = time; + this->key = key; + this->val = val; + } + bool operator<(const Node &n) const + { + if (n.cnt == cnt) + return time < n.time; + return cnt < n.cnt; + } +}; +class LFUCache +{ +public: + int size; + int time; + unordered_map LFU; + set tree; + LFUCache(int capacity) + { + time = 0; + size = capacity; + } + + int get(int key) + { + if (LFU.count(key) == 0) + return -1; + unordered_map::iterator iter = LFU.find(key); + Node now = (*iter).second; + tree.erase(now); + now.cnt++; + now.time = time++; + tree.insert(now); + (*iter).second = now; + return now.val; + } + void put(int key, int value) + { + if (LFU.count(key) == 0) + { + Node newNode = Node(1, time++, key, value); + if (size == 0) + { + if (tree.empty()) + return; + LFU.erase((*(tree.begin())).key); + tree.erase(tree.begin()); + } + else + { + size--; + } + LFU.insert(make_pair(key, newNode)); + tree.insert(newNode); + } + else + { + unordered_map::iterator iter = LFU.find(key); + Node now = (*iter).second; + tree.erase(now); + now.cnt++; + now.time = time++; + now.val = value; + tree.insert(now); + (*iter).second = now; + } + } +}; ``` ### B ```cpp +class LFUCache +{ +public: + LFUCache(int capacity_) + : capacity(capacity_), + minfreq(0) + { + iter_table.clear(); + freq_table.clear(); + } + + int get(int key) + { + if (capacity == 0) + return -1; + auto it = iter_table.find(key); + if (it == iter_table.end()) + return -1; + list::iterator iter = it->second; + + int value = iter->value; + int freq = iter->freq; + Value new_node(key, value, freq + 1); + + freq_table[freq].erase(iter); + if (freq_table[freq].size() == 0) + { + freq_table.erase(freq); + if (minfreq == freq) + minfreq += 1; + } + freq_table[freq + 1].push_front(new_node); + iter_table[key] = freq_table[freq + 1].begin(); + return new_node.value; + } + + void put(int key, int value) + { + if (capacity == 0) + return; + auto it = iter_table.find(key); + if (it == iter_table.end()) + { + + if (iter_table.size() == capacity) + { + auto it2 = freq_table[minfreq].back(); + iter_table.erase(it2.key); + freq_table[minfreq].pop_back(); + if (freq_table[minfreq].size() == 0) + { + freq_table.erase(minfreq); + } + } + freq_table[1].push_front(Value{key, value, 1}); + iter_table[key] = freq_table[1].begin(); + minfreq = 1; + } + else + { + list::iterator iter = it->second; + + int freq = iter->freq; + Value new_node(iter->key, value, freq + 1); + + freq_table[iter->freq].erase(iter); + + if (freq_table[freq].size() == 0) + { + freq_table.erase(freq); + if (minfreq == freq) + minfreq += 1; + } + freq_table[freq + 1].push_front(new_node); + iter_table[key] = freq_table[freq + 1].begin(); + } + } + +private: + struct Value + { + Value(int key_, int value_, int freq_) + : key(key_), + value(value_), + freq(freq_) {} + int key; + int value; + int freq; + }; + int capacity; + int minfreq; + unordered_map::iterator> iter_table; + unordered_map> freq_table; +}; ``` ### C ```cpp +struct Value +{ + Value(int count_, int time_, int key_, int value_) + : count(count_), + key(key_), + value(value_), + time(time_) {} + bool operator<(const Value &a) const + { + return count == a.count ? time < a.time : count < a.count; + } + int key; + int value; + int count; + int time; +}; +class LFUCache +{ +public: + LFUCache(int capacity_) + : capacity(capacity_), + time(0) {} + + int get(int key) + { + if (capacity == 0) + return -1; + auto it = table.find(key); + if (it == table.end()) + return -1; + Value cache = it->second; + judge.erase(cache); + cache.count++; + cache.time = ++time; + judge.insert(cache); + it->second = cache; + return cache.value; + } + + void put(int key, int value) + { + if (capacity == 0) + return; + auto it = table.find(key); + if (it == table.end()) + { + if (table.size() == capacity) + { + + table.erase(judge.begin()->key); + judge.erase(judge.begin()); + } + Value put_(0, ++time, key, value); + table.insert({key, put_}); + judge.insert(put_); + } + else + { + Value temp = it->second; + judge.erase(temp); + Value put_(++temp.count, ++time, key, value); + it->second = put_; + judge.insert(put_); + } + } + +private: + const int capacity; + int time; + unordered_map table; + set judge; +}; ``` diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/6.leetcode\345\223\210\345\270\214\350\241\250/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/config.json" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/6.leetcode\345\223\210\345\270\214\350\241\250/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/config.json" new file mode 100644 index 0000000000000000000000000000000000000000..8bc45104bf639a0afd1235502a0f8844898e9e4f --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/6.leetcode\345\223\210\345\270\214\350\241\250/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/config.json" @@ -0,0 +1,12 @@ +{ + "node_id": "569d5e11c4fc5de7844053d9a733c5e8", + "keywords": [ + "leetcode", + "同构字符串" + ], + "children": [], + "export": [ + "solution.json" + ], + "title": "同构字符串" +} \ No newline at end of file diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/6.leetcode\345\223\210\345\270\214\350\241\250/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/desc.html" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/6.leetcode\345\223\210\345\270\214\350\241\250/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/desc.html" new file mode 100644 index 0000000000000000000000000000000000000000..38508e175dab2bc57929de3dee89736a9e24f0ca --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/6.leetcode\345\223\210\345\270\214\350\241\250/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/desc.html" @@ -0,0 +1,34 @@ +

给定两个字符串 和 t,判断它们是否是同构的。

+ +

如果 中的字符可以按某种映射关系替换得到 ,那么这两个字符串是同构的。

+ +

每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。

+ +

 

+ +

示例 1:

+ +
+输入:s = "egg", t = "add"
+输出:true
+
+ +

示例 2:

+ +
+输入:s = "foo", t = "bar"
+输出:false
+ +

示例 3:

+ +
+输入:s = "paper", t = "title"
+输出:true
+ +

 

+ +

提示:

+ +
    +
  • 可以假设 t 长度相同。
  • +
diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/6.leetcode\345\223\210\345\270\214\350\241\250/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.cpp" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/6.leetcode\345\223\210\345\270\214\350\241\250/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.cpp" new file mode 100644 index 0000000000000000000000000000000000000000..099130411ef5cac9fa9f05dbad4e4bc26315c7cb --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/6.leetcode\345\223\210\345\270\214\350\241\250/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.cpp" @@ -0,0 +1,22 @@ +#include +using namespace std; + +class Solution +{ +public: + bool isIsomorphic(string s, string t) + { + unordered_map map1; + unordered_map map2; + int n = s.size(); + for (int i = 0; i < n; i++) + { + char x = s[i], y = t[i]; + if ((map1.count(x) && map1[x] != y) || (map2.count(y) && map2[y] != x)) + return false; + map1[x] = y; + map2[y] = x; + } + return true; + } +}; \ No newline at end of file diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/6.leetcode\345\223\210\345\270\214\350\241\250/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.json" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/6.leetcode\345\223\210\345\270\214\350\241\250/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.json" new file mode 100644 index 0000000000000000000000000000000000000000..f95e71cced8dec69722c84604d6babf097666fba --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/6.leetcode\345\223\210\345\270\214\350\241\250/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.json" @@ -0,0 +1,6 @@ +{ + "type": "code_options", + "author": "CSDN.net", + "source": "solution.md", + "exercise_id": "a015883ffc3d4b288ff1f75539a84980" +} \ No newline at end of file diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/6.leetcode\345\223\210\345\270\214\350\241\250/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.md" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/6.leetcode\345\223\210\345\270\214\350\241\250/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.md" new file mode 100644 index 0000000000000000000000000000000000000000..558af15fee4a1167d06c91acf34d1a2ed2b75fac --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/6.leetcode\345\223\210\345\270\214\350\241\250/204_\345\220\214\346\236\204\345\255\227\347\254\246\344\270\262/solution.md" @@ -0,0 +1,192 @@ +# 同构字符串 +

给定两个字符串 和 t,判断它们是否是同构的。

+ +

如果 中的字符可以按某种映射关系替换得到 ,那么这两个字符串是同构的。

+ +

每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。

+ +

 

+ +

示例 1:

+ +
+输入:s = "egg", t = "add"
+输出:true
+
+ +

示例 2:

+ +
+输入:s = "foo", t = "bar"
+输出:false
+ +

示例 3:

+ +
+输入:s = "paper", t = "title"
+输出:true
+ +

 

+ +

提示:

+ +
    +
  • 可以假设 t 长度相同。
  • +
+ +

以下错误的选项是?

+## aop +### before +```cpp +#include +using namespace std; +``` +### after +```cpp +int main() +{ + Solution sol; + string a = "egg"; + string b = "add"; + + bool res; + + res = sol.isIsomorphic(a, b); + cout << res; + return 0; +} +``` + +## 答案 +```cpp +class Solution +{ +public: + bool isIsomorphic(string s, string t) + { + if (s.size() != t.size()) + return false; + for (int i = 0; i < s.size(); i++) + { + int pos = s.find_first_of(s[i], i + 1); + while (pos != -1) + { + if (t[i] == t[pos + 1]) + { + s.erase(pos, 1); + t.erase(pos, 1); + pos = s.find_first_of(s[i], pos + 1); + } + else + return false; + } + } + for (int i = 0; i < t.size(); i++) + { + int pos = t.find_first_of(t[i], i + 1); + while (pos != -1) + { + if (s[i] == s[pos + 1]) + { + s.erase(pos, 1); + t.erase(pos, 1); + pos = t.find_first_of(t[i], pos + 1); + } + else + return false; + } + } + return true; + } +}; +``` +## 选项 + +### A +```cpp +class Solution +{ +public: + bool isIsomorphic(string s, string t) + { + if (s.size() != t.size()) + return false; + for (int i = 0; i < s.size(); i++) + { + if (s.find(s[i]) != t.find(t[i])) + return false; + } + return true; + } +}; +``` + +### B +```cpp +class Solution +{ +public: + bool isIsomorphic(string s, string t) + { + if (s.size() != t.size()) + return false; + for (int i = 0; i < s.size(); i++) + { + if (s[i] == s[i + 1]) + { + s.erase(i + 1, 1); + i--; + } + } + for (int i = 0; i < t.size(); i++) + { + if (t[i] == t[i + 1]) + { + t.erase(i + 1, 1); + i--; + } + } + if (s.size() != t.size()) + return false; + for (int i = 0; i < s.size(); i++) + { + int pos = s.find_first_of(s[i], i + 1); + while (pos != -1) + { + if (t[i] == t[pos]) + { + s.erase(pos, 1); + t.erase(pos, 1); + pos = s.find_first_of(s[i], pos + 1); + } + else + return false; + } + } + return true; + } +}; +``` + +### C +```cpp +class Solution +{ +public: + bool isIsomorphic(string s, string t) + { + unordered_map map1; + unordered_map map2; + int n = s.size(); + for (int i = 0; i < n; i++) + { + char x = s[i], y = t[i]; + if ((map1.count(x) && map1[x] != y) || (map2.count(y) && map2[y] != x)) + return false; + map1[x] = y; + map2[y] = x; + } + return true; + } +}; +``` diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/config.json" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/config.json" new file mode 100644 index 0000000000000000000000000000000000000000..57ac85a91436af34c996f57168052a3c3e7224d4 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/config.json" @@ -0,0 +1,12 @@ +{ + "node_id": "569d5e11c4fc5de7844053d9a733c5e8", + "keywords": [ + "leetcode", + "LRU 缓存机制" + ], + "children": [], + "export": [ + "solution.json" + ], + "title": "LRU 缓存机制" +} \ No newline at end of file diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/desc.html" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/desc.html" new file mode 100644 index 0000000000000000000000000000000000000000..2305713e8d826b5c079166c78ffce66263c3ac14 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/desc.html" @@ -0,0 +1,52 @@ +
运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制
+ +
+
+

实现 LRUCache 类:

+ +
    +
  • LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
  • +
  • int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1
  • +
  • void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
  • +
+ +

 

+
+
+ +

进阶:你是否可以在 O(1) 时间复杂度内完成这两种操作?

+ +

 

+ +

示例:

+ +
+输入
+["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
+[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
+输出
+[null, null, null, 1, null, -1, null, -1, 3, 4]
+
+解释
+LRUCache lRUCache = new LRUCache(2);
+lRUCache.put(1, 1); // 缓存是 {1=1}
+lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
+lRUCache.get(1);    // 返回 1
+lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
+lRUCache.get(2);    // 返回 -1 (未找到)
+lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
+lRUCache.get(1);    // 返回 -1 (未找到)
+lRUCache.get(3);    // 返回 3
+lRUCache.get(4);    // 返回 4
+
+ +

 

+ +

提示:

+ +
    +
  • 1 <= capacity <= 3000
  • +
  • 0 <= key <= 10000
  • +
  • 0 <= value <= 105
  • +
  • 最多调用 2 * 105getput
  • +
diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/solution.cpp" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/solution.cpp" new file mode 100644 index 0000000000000000000000000000000000000000..b4a375907bba6014a15de7f6abb2c195eb8025e2 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/solution.cpp" @@ -0,0 +1,43 @@ +class LRUCache +{ +public: + LRUCache(int capacity) : cap(capacity) {} + + int get(int key) + { + if (m.count(key) != 0) + { + int val = m[key]->second; + l.erase(m[key]); + l.push_front({key, val}); //访问过的元素移动到头部 + m[key] = l.begin(); + return val; + } + return -1; + } + + void put(int key, int value) + { + if (m.count(key) != 0) + { //已经存在 + l.erase(m[key]); + l.push_front({key, value}); + m[key] = l.begin(); + } + else + { + if (l.size() == cap) + { //同步删除 + m.erase(l.back().first); + l.pop_back(); + } + l.push_front({key, value}); + m[key] = l.begin(); + } + } + +private: + int cap; + list> l; + unordered_map>::iterator> m; +}; diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/solution.json" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/solution.json" new file mode 100644 index 0000000000000000000000000000000000000000..6bd5a48651051ad9526a1c2e40a5c9fff1cf3b6b --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/solution.json" @@ -0,0 +1,6 @@ +{ + "type": "code_options", + "author": "CSDN.net", + "source": "solution.md", + "exercise_id": "97c15992ec93466ba46bf6a7ca1463e0" +} \ No newline at end of file diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/solution.md" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/solution.md" new file mode 100644 index 0000000000000000000000000000000000000000..202817893aeb8f1eb2bfd96a03877a0ded025cda --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/145_LRU \347\274\223\345\255\230\346\234\272\345\210\266/solution.md" @@ -0,0 +1,314 @@ +# LRU 缓存机制 +
运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制
+ +
+
+

实现 LRUCache 类:

+ +
    +
  • LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
  • +
  • int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1
  • +
  • void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
  • +
+ +

 

+
+
+ +

进阶:你是否可以在 O(1) 时间复杂度内完成这两种操作?

+ +

 

+ +

示例:

+ +
+输入
+["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
+[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
+输出
+[null, null, null, 1, null, -1, null, -1, 3, 4]
+
+解释
+LRUCache lRUCache = new LRUCache(2);
+lRUCache.put(1, 1); // 缓存是 {1=1}
+lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
+lRUCache.get(1);    // 返回 1
+lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
+lRUCache.get(2);    // 返回 -1 (未找到)
+lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
+lRUCache.get(1);    // 返回 -1 (未找到)
+lRUCache.get(3);    // 返回 3
+lRUCache.get(4);    // 返回 4
+
+ +

 

+ +

提示:

+ +
    +
  • 1 <= capacity <= 3000
  • +
  • 0 <= key <= 10000
  • +
  • 0 <= value <= 105
  • +
  • 最多调用 2 * 105getput
  • +
+ +

以下错误的选项是?

+## aop +### before +```cpp +#include +using namespace std; +``` +### after +```cpp + +``` + +## 答案 +```cpp +class LRUCache +{ +public: + LRUCache(int capacity) : cap(capacity) {} + + int get(int key) + { + if (m.count(key) != 0) + { + int val = m[key]->second; + l.erase(m[key]); + l.push_front({key, val}); + m[key] = l.begin(); + return val; + } + return -1; + } + + void put(int key, int value) + { + if (m.count(key) != 0) + { + l.erase(m[key]); + l.push_front({key, value}); + m[key] = l.begin(); + } + else + { + m.erase(l.back().first); + l.pop_back(); + l.push_front({key, value}); + m[key] = l.begin(); + } + } + +private: + int cap; + list> l; + unordered_map>::iterator> m; +}; +``` +## 选项 + +### A +```cpp +class LRUCache +{ +private: + unordered_map cache; + DLinkedNode *head; + DLinkedNode *tail; + int size; + int capacity; + +public: + LRUCache(int _capacity) : capacity(_capacity), size(0) + { + + head = new DLinkedNode(); + tail = new DLinkedNode(); + head->next = tail; + tail->prev = head; + } + + int get(int key) + { + if (!cache.count(key)) + { + return -1; + } + + DLinkedNode *node = cache[key]; + moveToHead(node); + return node->value; + } + + void put(int key, int value) + { + if (!cache.count(key)) + { + + DLinkedNode *node = new DLinkedNode(key, value); + + cache[key] = node; + + addToHead(node); + ++size; + if (size > capacity) + { + + DLinkedNode *removed = removeTail(); + + cache.erase(removed->key); + + delete removed; + --size; + } + } + else + { + + DLinkedNode *node = cache[key]; + node->value = value; + moveToHead(node); + } + } + + void addToHead(DLinkedNode *node) + { + node->prev = head; + node->next = head->next; + head->next->prev = node; + head->next = node; + } + + void removeNode(DLinkedNode *node) + { + node->prev->next = node->next; + + node->next->prev = node->prev; + } + + void moveToHead(DLinkedNode *node) + { + removeNode(node); + addToHead(node); + } + + DLinkedNode *removeTail() + { + DLinkedNode *node = tail->prev; + removeNode(node); + return node; + } +}; +``` + +### B +```cpp +class LRUCache +{ +private: + int capacity; + list> cl; + unordered_map>::iterator> cm; + +public: + LRUCache(int capacity) + { + this->capacity = capacity; + } + + int get(int key) + { + auto it = cm.find(key); + if (it != cm.end()) + { + pair p = *cm[key]; + int value = p.second; + cl.erase(cm[key]); + cl.push_front(p); + cm[key] = cl.begin(); + return value; + } + else + return -1; + } + + void put(int key, int value) + { + auto it = cm.find(key); + if (it != cm.end()) + { + cl.erase(cm[key]); + cl.push_front({key, value}); + cm[key] = cl.begin(); + } + else + { + if (cl.size() == capacity) + { + int old_key = cl.back().first; + cl.pop_back(); + cm.erase(old_key); + } + cl.push_front({key, value}); + cm.insert({key, cl.begin()}); + } + } +}; +``` + +### C +```cpp +class LRUCache +{ +private: + int capacity, size; + list cl; + unordered_map cm; + +public: + LRUCache(int capacity) + { + this->capacity = capacity; + size = 0; + } + + int get(int key) + { + auto it = cm.find(key); + if (it != cm.end()) + { + cl.remove(key); + cl.push_back(key); + return it->second; + } + else + return -1; + } + + void put(int key, int value) + { + auto it = cm.find(key); + if (it != cm.end()) + { + it->second = value; + cl.remove(key); + cl.push_back(key); + } + else + { + if (size == capacity) + { + int old_key = cl.front(); + cl.pop_front(); + cm.erase(old_key); + size--; + } + cl.push_back(key); + cm.insert({key, value}); + size++; + } + } +}; +``` diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/354_\350\256\276\350\256\241\346\216\250\347\211\271/config.json" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/354_\350\256\276\350\256\241\346\216\250\347\211\271/config.json" new file mode 100644 index 0000000000000000000000000000000000000000..62d50a0745523ebffda3e3c379c572a90ef32e58 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/354_\350\256\276\350\256\241\346\216\250\347\211\271/config.json" @@ -0,0 +1,12 @@ +{ + "node_id": "569d5e11c4fc5de7844053d9a733c5e8", + "keywords": [ + "leetcode", + "设计推特" + ], + "children": [], + "export": [ + "solution.json" + ], + "title": "设计推特" +} \ No newline at end of file diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/354_\350\256\276\350\256\241\346\216\250\347\211\271/desc.html" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/354_\350\256\276\350\256\241\346\216\250\347\211\271/desc.html" new file mode 100644 index 0000000000000000000000000000000000000000..cb87df3594f3e1d72b82c55d9b3efa2f831a85fa --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/354_\350\256\276\350\256\241\346\216\250\347\211\271/desc.html" @@ -0,0 +1,43 @@ +

设计一个简化版的推特(Twitter),可以让用户实现发送推文,关注/取消关注其他用户,能够看见关注人(包括自己)的最近 10 条推文。

+ +

实现 Twitter 类:

+ +
    +
  • Twitter() 初始化简易版推特对象
  • +
  • void postTweet(int userId, int tweetId) 根据给定的 tweetIduserId 创建一条新推文。每次调用次函数都会使用一个不同的 tweetId
  • +
  • List<Integer> getNewsFeed(int userId) 检索当前用户新闻推送中最近  10 条推文的 ID 。新闻推送中的每一项都必须是由用户关注的人或者是用户自己发布的推文。推文必须 按照时间顺序由最近到最远排序
  • +
  • void follow(int followerId, int followeeId) ID 为 followerId 的用户开始关注 ID 为 followeeId 的用户。
  • +
  • void unfollow(int followerId, int followeeId) ID 为 followerId 的用户不再关注 ID 为 followeeId 的用户。
  • +
+ +

 

+ +

示例:

+ +
+输入
+["Twitter", "postTweet", "getNewsFeed", "follow", "postTweet", "getNewsFeed", "unfollow", "getNewsFeed"]
+[[], [1, 5], [1], [1, 2], [2, 6], [1], [1, 2], [1]]
+输出
+[null, null, [5], null, null, [6, 5], null, [5]]
+
+解释
+Twitter twitter = new Twitter();
+twitter.postTweet(1, 5); // 用户 1 发送了一条新推文 (用户 id = 1, 推文 id = 5)
+twitter.getNewsFeed(1);  // 用户 1 的获取推文应当返回一个列表,其中包含一个 id 为 5 的推文
+twitter.follow(1, 2);    // 用户 1 关注了用户 2
+twitter.postTweet(2, 6); // 用户 2 发送了一个新推文 (推文 id = 6)
+twitter.getNewsFeed(1);  // 用户 1 的获取推文应当返回一个列表,其中包含两个推文,id 分别为 -> [6, 5] 。推文 id 6 应当在推文 id 5 之前,因为它是在 5 之后发送的
+twitter.unfollow(1, 2);  // 用户 1 取消关注了用户 2
+twitter.getNewsFeed(1);  // 用户 1 获取推文应当返回一个列表,其中包含一个 id 为 5 的推文。因为用户 1 已经不再关注用户 2
+ +

 

+ +

提示:

+ +
    +
  • 1 <= userId, followerId, followeeId <= 500
  • +
  • 0 <= tweetId <= 104
  • +
  • 所有推特的 ID 都互不相同
  • +
  • postTweetgetNewsFeedfollowunfollow 方法最多调用 3 * 104
  • +
diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.cpp" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.cpp" new file mode 100644 index 0000000000000000000000000000000000000000..d471cd99a661cd41b3cb74004f263d2ddacb3905 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.cpp" @@ -0,0 +1,62 @@ +#include +using namespace std; + +class Twitter +{ +public: + /** Initialize your data structure here. */ + Twitter() + { + } + + /** Compose a new tweet. */ + void postTweet(int userId, int tweetId) + { + context.push_back(make_pair(userId, tweetId)); + } + + /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */ + vector getNewsFeed(int userId) + { + int n = context.size(); + int count = 0; + vector res; + int k = n - 1; + while (count < 10 && k >= 0) + { + auto it = context[k]; + if (it.first == userId || tmp[make_pair(userId, it.first)]) + { + res.push_back(context[k].second); + count++; + } + k--; + } + return res; + } + + /** Follower follows a followee. If the operation is invalid, it should be a no-op. */ + void follow(int followerId, int followeeId) + { + tmp[make_pair(followerId, followeeId)] = 1; + } + + /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ + void unfollow(int followerId, int followeeId) + { + tmp[make_pair(followerId, followeeId)] = 0; + } + +private: + map, int> tmp; + vector> context; +}; + +/** + * Your Twitter object will be instantiated and called as such: + * Twitter* obj = new Twitter(); + * obj->postTweet(userId,tweetId); + * vector param_2 = obj->getNewsFeed(userId); + * obj->follow(followerId,followeeId); + * obj->unfollow(followerId,followeeId); + */ diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.json" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.json" new file mode 100644 index 0000000000000000000000000000000000000000..73f88cb66cea5f07dec315f0aa910358841096bb --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.json" @@ -0,0 +1,6 @@ +{ + "type": "code_options", + "author": "CSDN.net", + "source": "solution.md", + "exercise_id": "513aa99c029d4aa6a7b04c2008a13dbf" +} \ No newline at end of file diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.md" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.md" new file mode 100644 index 0000000000000000000000000000000000000000..5c8f5ba370d32de1acc89cf9e31b54a7f762b571 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/354_\350\256\276\350\256\241\346\216\250\347\211\271/solution.md" @@ -0,0 +1,350 @@ +# 设计推特 +

设计一个简化版的推特(Twitter),可以让用户实现发送推文,关注/取消关注其他用户,能够看见关注人(包括自己)的最近 10 条推文。

+ +

实现 Twitter 类:

+ +
    +
  • Twitter() 初始化简易版推特对象
  • +
  • void postTweet(int userId, int tweetId) 根据给定的 tweetIduserId 创建一条新推文。每次调用次函数都会使用一个不同的 tweetId
  • +
  • List<Integer> getNewsFeed(int userId) 检索当前用户新闻推送中最近  10 条推文的 ID 。新闻推送中的每一项都必须是由用户关注的人或者是用户自己发布的推文。推文必须 按照时间顺序由最近到最远排序
  • +
  • void follow(int followerId, int followeeId) ID 为 followerId 的用户开始关注 ID 为 followeeId 的用户。
  • +
  • void unfollow(int followerId, int followeeId) ID 为 followerId 的用户不再关注 ID 为 followeeId 的用户。
  • +
+ +

 

+ +

示例:

+ +
+输入
+["Twitter", "postTweet", "getNewsFeed", "follow", "postTweet", "getNewsFeed", "unfollow", "getNewsFeed"]
+[[], [1, 5], [1], [1, 2], [2, 6], [1], [1, 2], [1]]
+输出
+[null, null, [5], null, null, [6, 5], null, [5]]
+
+解释
+Twitter twitter = new Twitter();
+twitter.postTweet(1, 5); // 用户 1 发送了一条新推文 (用户 id = 1, 推文 id = 5)
+twitter.getNewsFeed(1);  // 用户 1 的获取推文应当返回一个列表,其中包含一个 id 为 5 的推文
+twitter.follow(1, 2);    // 用户 1 关注了用户 2
+twitter.postTweet(2, 6); // 用户 2 发送了一个新推文 (推文 id = 6)
+twitter.getNewsFeed(1);  // 用户 1 的获取推文应当返回一个列表,其中包含两个推文,id 分别为 -> [6, 5] 。推文 id 6 应当在推文 id 5 之前,因为它是在 5 之后发送的
+twitter.unfollow(1, 2);  // 用户 1 取消关注了用户 2
+twitter.getNewsFeed(1);  // 用户 1 获取推文应当返回一个列表,其中包含一个 id 为 5 的推文。因为用户 1 已经不再关注用户 2
+ +

 

+ +

提示:

+ +
    +
  • 1 <= userId, followerId, followeeId <= 500
  • +
  • 0 <= tweetId <= 104
  • +
  • 所有推特的 ID 都互不相同
  • +
  • postTweetgetNewsFeedfollowunfollow 方法最多调用 3 * 104
  • +
+ +

以下错误的选项是?

+## aop +### before +```cpp +#include +using namespace std; +``` +### after +```cpp + +``` + +## 答案 +```cpp +class Twitter +{ +public: + /** Initialize your data structure here. */ + Twitter() + { + } + + /** Compose a new tweet. */ + void postTweet(int userId, int tweetId) + { + tweets[userId].push_back(make_pair(time++, tweetId)); + } + + /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */ + vector getNewsFeed(int userId) + { + vector userIds({userId}); + if (following.find(userId) != following.end()) + { + userIds.insert(userIds.begin(), following[userId].begin(), following[userId].end()); + } + + vector index(userIds.size()); + for (int i = 0; i < userIds.size(); ++i) + { + index[i] = tweets[userIds[i]].size(); + } + + vector res; + while (res.size() < 10) + { + int mxi = 0, mxtime = INT_MIN, mxTweet = 0; + for (int i = 0; i < index.size(); ++i) + { + int idx = index[i]; + if (idx > 0) + { + int ui = userIds[i]; + int time = tweets[ui][idx].first; + if (time > mxtime) + { + mxi = i; + mxtime = time; + mxTweet = tweets[ui][idx].second; + } + } + } + + if (mxtime == INT_MIN) + { + break; + } + + ++index[mxi]; + res.push_back(mxTweet); + } + + return res; + } + + /** Follower follows a followee. If the operation is invalid, it should be a no-op. */ + void follow(int followerId, int followeeId) + { + if (followerId != followeeId) + { + following[followerId].insert(followeeId); + } + } + + /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ + void unfollow(int followerId, int followeeId) + { + if (following.find(followerId) == following.end()) + { + return; + } + following[followerId].erase(followeeId); + if (following[followerId].empty()) + { + following.erase(followerId); + } + } + +private: + int time{0}; + unordered_map> following; + unordered_map>> tweets; +}; +/** + * Your Twitter object will be instantiated and called as such: + * Twitter obj = new Twitter(); + * obj.postTweet(userId,tweetId); + * vector param_2 = obj.getNewsFeed(userId); + * obj.follow(followerId,followeeId); + * obj.unfollow(followerId,followeeId); + */ + +``` +## 选项 + +### A +```cpp +class Twitter +{ +private: + list> twitterNews; + map> followMap; + +public: + /** Initialize your data structure here. */ + Twitter() + { + } + + /** Compose a new tweet. */ + void postTweet(int userId, int tweetId) + { + + twitterNews.insert(twitterNews.begin(), pair(userId, tweetId)); + } + + /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */ + vector getNewsFeed(int userId) + { + vector result; + list>::iterator it = twitterNews.begin(); + + while (it != twitterNews.end() && result.size() < 10) + { + + if (it->first == userId || followMap[userId][it->first]) + { + result.push_back(it->second); + } + it++; + } + return result; + } + + /** Follower follows a followee. If the operation is invalid, it should be a no-op. */ + void follow(int followerId, int followeeId) + { + followMap[followerId][followeeId] = true; + } + + /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ + void unfollow(int followerId, int followeeId) + { + followMap[followerId][followeeId] = false; + } +}; + +/** + * Your Twitter object will be instantiated and called as such: + * Twitter obj = new Twitter(); + * obj.postTweet(userId,tweetId); + * vector param_2 = obj.getNewsFeed(userId); + * obj.follow(followerId,followeeId); + * obj.unfollow(followerId,followeeId); + */ + +``` + +### B +```cpp +class Twitter +{ +public: + /** Initialize your data structure here. */ + Twitter() + { + } + + /** Compose a new tweet. */ + void postTweet(int userId, int tweetId) + { + context.push_back(make_pair(userId, tweetId)); + } + + /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */ + vector getNewsFeed(int userId) + { + int n = context.size(); + int count = 0; + vector res; + int k = n - 1; + while (count < 10 && k >= 0) + { + auto it = context[k]; + if (it.first == userId || tmp[make_pair(userId, it.first)]) + { + res.push_back(context[k].second); + count++; + } + k--; + } + return res; + } + + /** Follower follows a followee. If the operation is invalid, it should be a no-op. */ + void follow(int followerId, int followeeId) + { + tmp[make_pair(followerId, followeeId)] = 1; + } + + /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ + void unfollow(int followerId, int followeeId) + { + tmp[make_pair(followerId, followeeId)] = 0; + } + +private: + map, int> tmp; + vector> context; +}; + +/** + * Your Twitter object will be instantiated and called as such: + * Twitter* obj = new Twitter(); + * obj->postTweet(userId,tweetId); + * vector param_2 = obj->getNewsFeed(userId); + * obj->follow(followerId,followeeId); + * obj->unfollow(followerId,followeeId); + */ + +``` + +### C +```cpp +class Twitter +{ +public: + /** Initialize your data structure here. */ + Twitter() + { + } + + /** Compose a new tweet. */ + void postTweet(int userId, int tweetId) + { + context.push_back(make_pair(userId, tweetId)); + } + + /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */ + vector getNewsFeed(int userId) + { + int n = context.size(); + int count = 0; + vector res; + int k = n - 1; + while (count < 10 && k >= 0) + { + auto it = context[k]; + if (it.first == userId || tmp[make_pair(userId, it.first)]) + { + res.push_back(context[k].second); + count++; + } + k--; + } + return res; + } + + /** Follower follows a followee. If the operation is invalid, it should be a no-op. */ + void follow(int followerId, int followeeId) + { + tmp[make_pair(followerId, followeeId)] = 1; + } + + /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ + void unfollow(int followerId, int followeeId) + { + tmp[make_pair(followerId, followeeId)] = 0; + } + +private: + map, int> tmp; + vector> context; +}; + +/** + * Your Twitter object will be instantiated and called as such: + * Twitter* obj = new Twitter(); + * obj->postTweet(userId,tweetId); + * vector param_2 = obj->getNewsFeed(userId); + * obj->follow(followerId,followeeId); + * obj->unfollow(followerId,followeeId); + */ + +``` diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/config.json" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/config.json" new file mode 100644 index 0000000000000000000000000000000000000000..80215632f0c7fb391605d0454f3ee84f9d5d52a9 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/config.json" @@ -0,0 +1,12 @@ +{ + "node_id": "569d5e11c4fc5de7844053d9a733c5e8", + "keywords": [ + "leetcode", + "O(1) 时间插入、删除和获取随机元素" + ], + "children": [], + "export": [ + "solution.json" + ], + "title": "O(1) 时间插入、删除和获取随机元素" +} \ No newline at end of file diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/desc.html" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/desc.html" new file mode 100644 index 0000000000000000000000000000000000000000..9a07dbe4fcb72e3caa11a380ad6f03a65d0599a2 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/desc.html" @@ -0,0 +1,46 @@ +

实现RandomizedSet 类:

+ +
+
+
    +
  • RandomizedSet() 初始化 RandomizedSet 对象
  • +
  • bool insert(int val) 当元素 val 不存在时,向集合中插入该项,并返回 true ;否则,返回 false
  • +
  • bool remove(int val) 当元素 val 存在时,从集合中移除该项,并返回 true ;否则,返回 false
  • +
  • int getRandom() 随机返回现有集合中的一项(测试用例保证调用此方法时集合中至少存在一个元素)。每个元素应该有 相同的概率 被返回。
  • +
+ +

你必须实现类的所有函数,并满足每个函数的 平均 时间复杂度为 O(1)

+ +

 

+ +

示例:

+ +
+输入
+["RandomizedSet", "insert", "remove", "insert", "getRandom", "remove", "insert", "getRandom"]
+[[], [1], [2], [2], [], [1], [2], []]
+输出
+[null, true, false, true, 2, true, false, 2]
+
+解释
+RandomizedSet randomizedSet = new RandomizedSet();
+randomizedSet.insert(1); // 向集合中插入 1 。返回 true 表示 1 被成功地插入。
+randomizedSet.remove(2); // 返回 false ,表示集合中不存在 2 。
+randomizedSet.insert(2); // 向集合中插入 2 。返回 true 。集合现在包含 [1,2] 。
+randomizedSet.getRandom(); // getRandom 应随机返回 1 或 2 。
+randomizedSet.remove(1); // 从集合中移除 1 ,返回 true 。集合现在包含 [2] 。
+randomizedSet.insert(2); // 2 已在集合中,所以返回 false 。
+randomizedSet.getRandom(); // 由于 2 是集合中唯一的数字,getRandom 总是返回 2 。
+
+ +

 

+ +

提示:

+ +
    +
  • -231 <= val <= 231 - 1
  • +
  • 最多调用 insertremovegetRandom 函数 2 * 105
  • +
  • 在调用 getRandom 方法时,数据结构中 至少存在一个 元素。
  • +
+
+
diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.cpp" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.cpp" new file mode 100644 index 0000000000000000000000000000000000000000..6051691a755fc6d23bf9d956ed183591dff67fe3 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.cpp" @@ -0,0 +1,47 @@ +#include +using namespace std; + +class RandomizedSet +{ +public: + vector nums; + unordered_map nums_inds; + /** Initialize your data structure here. */ + RandomizedSet() + { + } + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + bool insert(int val) + { + if (nums_inds.count(val) != 0) + return false; + nums.push_back(val); + nums_inds[val] = nums.size() - 1; + return true; + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + bool remove(int val) + { + if (nums_inds.count(val) == 0) + return false; + + int last = nums.back(); + int ind = nums_inds[val]; + + nums[ind] = last; + nums_inds[last] = ind; + + nums.pop_back(); + nums_inds.erase(val); + return true; + } + + /** Get a random element from the set. */ + int getRandom() + { + int ind = rand() % nums.size(); + return nums[ind]; + } +}; diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.json" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.json" new file mode 100644 index 0000000000000000000000000000000000000000..325e84a2e7d140792b6510c3ed2adb581c8e1366 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.json" @@ -0,0 +1,6 @@ +{ + "type": "code_options", + "author": "CSDN.net", + "source": "solution.md", + "exercise_id": "af4861dc9e9b4bdba981f858f56483e7" +} \ No newline at end of file diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.md" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.md" new file mode 100644 index 0000000000000000000000000000000000000000..50bb832bda98197e1dc7bd4294816296250705da --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/379_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240/solution.md" @@ -0,0 +1,253 @@ +# O(1) 时间插入、删除和获取随机元素 +

实现RandomizedSet 类:

+ +
+
+
    +
  • RandomizedSet() 初始化 RandomizedSet 对象
  • +
  • bool insert(int val) 当元素 val 不存在时,向集合中插入该项,并返回 true ;否则,返回 false
  • +
  • bool remove(int val) 当元素 val 存在时,从集合中移除该项,并返回 true ;否则,返回 false
  • +
  • int getRandom() 随机返回现有集合中的一项(测试用例保证调用此方法时集合中至少存在一个元素)。每个元素应该有 相同的概率 被返回。
  • +
+ +

你必须实现类的所有函数,并满足每个函数的 平均 时间复杂度为 O(1)

+ +

 

+ +

示例:

+ +
+输入
+["RandomizedSet", "insert", "remove", "insert", "getRandom", "remove", "insert", "getRandom"]
+[[], [1], [2], [2], [], [1], [2], []]
+输出
+[null, true, false, true, 2, true, false, 2]
+
+解释
+RandomizedSet randomizedSet = new RandomizedSet();
+randomizedSet.insert(1); // 向集合中插入 1 。返回 true 表示 1 被成功地插入。
+randomizedSet.remove(2); // 返回 false ,表示集合中不存在 2 。
+randomizedSet.insert(2); // 向集合中插入 2 。返回 true 。集合现在包含 [1,2] 。
+randomizedSet.getRandom(); // getRandom 应随机返回 1 或 2 。
+randomizedSet.remove(1); // 从集合中移除 1 ,返回 true 。集合现在包含 [2] 。
+randomizedSet.insert(2); // 2 已在集合中,所以返回 false 。
+randomizedSet.getRandom(); // 由于 2 是集合中唯一的数字,getRandom 总是返回 2 。
+
+ +

 

+ +

提示:

+ +
    +
  • -231 <= val <= 231 - 1
  • +
  • 最多调用 insertremovegetRandom 函数 2 * 105
  • +
  • 在调用 getRandom 方法时,数据结构中 至少存在一个 元素。
  • +
+
+
+ +

以下错误的选项是?

+## aop +### before +```cpp +#include +using namespace std; + +``` +### after +```cpp + +``` + +## 答案 +```cpp +class RandomizedSet +{ + unordered_map dict; + vector list; + +public: + /** Initialize your data structure here. */ + RandomizedSet() + { + srand(time(0)); + } + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + bool insert(int val) + { + if (dict.find(val) != dict.end()) + return false; + list.push_back(val); + dict[val] = list.size(); + return true; + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + bool remove(int val) + { + if (dict.find(val) == dict.end()) + return false; + dict[list.back()] = dict[val]; + swap(list.back(), list[dict[val]]); + list.pop_back(); + dict.erase(val); + return true; + } + + /** Get a random element from the set. */ + int getRandom() + { + int pos = list.empty() ? 0 : rand() % list.size(); + return list[pos]; + } +}; +``` +## 选项 + +### A +```cpp +class RandomizedSet +{ +public: + /** Initialize your data structure here. */ + RandomizedSet() + { + } + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + bool insert(int val) + { + if (mMap.count(val) > 0) + return false; + + mData.push_back(val); + mMap[val] = mData.size() - 1; + return true; + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + bool remove(int val) + { + + if (mMap.count(val) > 0) + { + int last_num = mData.back(); + int val_index = mMap[val]; + mData[val_index] = last_num; + mMap[last_num] = val_index; + + mData.pop_back(); + mMap.erase(val); + + return true; + } + + return false; + } + + /** Get a random element from the set. */ + int getRandom() + { + int index = rand() % mData.size(); + return mData[index]; + } + +private: + vector mData; + unordered_map mMap; +}; +``` + +### B +```cpp +class RandomizedSet +{ +public: + unordered_set ust; + + /** Initialize your data structure here. */ + RandomizedSet() + { + } + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + bool insert(int val) + { + if (ust.find(val) != ust.end()) + return false; + ust.insert(val); + return true; + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + bool remove(int val) + { + if (ust.find(val) == ust.end()) + return false; + ust.erase(val); + return true; + } + + /** Get a random element from the set. */ + int getRandom() + { + int ind = rand() % ust.size(); + auto it = ust.begin(); + for (int i = 0; i < ind; i++) + { + it++; + } + return *it; + } +}; +``` + +### C +```cpp +class RandomizedSet +{ +public: + vector nums; + unordered_map nums_inds; + /** Initialize your data structure here. */ + RandomizedSet() + { + } + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + bool insert(int val) + { + if (nums_inds.count(val) != 0) + return false; + nums.push_back(val); + nums_inds[val] = nums.size() - 1; + return true; + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + bool remove(int val) + { + if (nums_inds.count(val) == 0) + return false; + + int last = nums.back(); + int ind = nums_inds[val]; + + nums[ind] = last; + nums_inds[last] = ind; + + nums.pop_back(); + nums_inds.erase(val); + return true; + } + + /** Get a random element from the set. */ + int getRandom() + { + int ind = rand() % nums.size(); + return nums[ind]; + } +}; + +``` diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/config.json" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/config.json" new file mode 100644 index 0000000000000000000000000000000000000000..c8b9c1dd61c5273d4e06e10e912d4806fdd60d1a --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/config.json" @@ -0,0 +1,12 @@ +{ + "node_id": "569d5e11c4fc5de7844053d9a733c5e8", + "keywords": [ + "leetcode", + "O(1) 时间插入、删除和获取随机元素 - 允许重复" + ], + "children": [], + "export": [ + "solution.json" + ], + "title": "O(1) 时间插入、删除和获取随机元素 - 允许重复" +} \ No newline at end of file diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/desc.html" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/desc.html" new file mode 100644 index 0000000000000000000000000000000000000000..2405d13edd41df743eb5823ec705ed2ccb62e0ac --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/desc.html" @@ -0,0 +1,33 @@ +

设计一个支持在平均 时间复杂度 O(1) , 执行以下操作的数据结构。

+ +

注意: 允许出现重复元素。

+ +
    +
  1. insert(val):向集合中插入元素 val。
  2. +
  3. remove(val):当 val 存在时,从集合中移除一个 val。
  4. +
  5. getRandom:从现有集合中随机获取一个元素。每个元素被返回的概率应该与其在集合中的数量呈线性相关。
  6. +
+ +

示例:

+ +
// 初始化一个空的集合。
+RandomizedCollection collection = new RandomizedCollection();
+
+// 向集合中插入 1 。返回 true 表示集合不包含 1 。
+collection.insert(1);
+
+// 向集合中插入另一个 1 。返回 false 表示集合包含 1 。集合现在包含 [1,1] 。
+collection.insert(1);
+
+// 向集合中插入 2 ,返回 true 。集合现在包含 [1,1,2] 。
+collection.insert(2);
+
+// getRandom 应当有 2/3 的概率返回 1 ,1/3 的概率返回 2 。
+collection.getRandom();
+
+// 从集合中删除 1 ,返回 true 。集合现在包含 [1,2] 。
+collection.remove(1);
+
+// getRandom 应有相同概率返回 1 和 2 。
+collection.getRandom();
+
diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.cpp" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.cpp" new file mode 100644 index 0000000000000000000000000000000000000000..ae849919b82ddbcd0c49881c977f7e001cc48b28 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.cpp" @@ -0,0 +1,60 @@ +#include +using namespace std; + +class RandomizedCollection +{ +public: + vector nums; + unordered_map> numsIndex; + int size; + /** Initialize your data structure here. */ + RandomizedCollection() + { + size = 0; + } + + /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ + bool insert(int val) + { + nums.push_back(val); + numsIndex[val].insert(size); + size++; + return numsIndex[val].size() == 1; + } + + /** Removes a value from the collection. Returns true if the collection contained the specified element. */ + bool remove(int val) + { + if (numsIndex.count(val) == 0) + return false; + int last = nums.back(); + int id = size - 1; + if (last != val) + { + id = *(numsIndex[val].begin()); + numsIndex[last].erase(size - 1); + numsIndex[last].insert(id); + nums[id] = last; + } + nums.pop_back(); + size--; + numsIndex[val].erase(id); + if (numsIndex[val].empty()) + numsIndex.erase(val); + return true; + } + + /** Get a random element from the collection. */ + int getRandom() + { + return nums[random() % size]; + } +}; + +/** + * Your RandomizedCollection object will be instantiated and called as such: + * RandomizedCollection* obj = new RandomizedCollection(); + * bool param_1 = obj->insert(val); + * bool param_2 = obj->remove(val); + * int param_3 = obj->getRandom(); + */ diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.json" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.json" new file mode 100644 index 0000000000000000000000000000000000000000..7bf80332cc05f9fb8d7546b815be9d21a649158a --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.json" @@ -0,0 +1,6 @@ +{ + "type": "code_options", + "author": "CSDN.net", + "source": "solution.md", + "exercise_id": "d2333bf24b234247806d53c1ec803df7" +} \ No newline at end of file diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.md" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.md" new file mode 100644 index 0000000000000000000000000000000000000000..d6bb395d839cfd55ea6c84c535c2c880b9c0d2e5 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/380_O(1) \346\227\266\351\227\264\346\217\222\345\205\245\343\200\201\345\210\240\351\231\244\345\222\214\350\216\267\345\217\226\351\232\217\346\234\272\345\205\203\347\264\240 - \345\205\201\350\256\270\351\207\215\345\244\215/solution.md" @@ -0,0 +1,266 @@ +# O(1) 时间插入、删除和获取随机元素 - 允许重复 +

设计一个支持在平均 时间复杂度 O(1) , 执行以下操作的数据结构。

+ +

注意: 允许出现重复元素。

+ +
    +
  1. insert(val):向集合中插入元素 val。
  2. +
  3. remove(val):当 val 存在时,从集合中移除一个 val。
  4. +
  5. getRandom:从现有集合中随机获取一个元素。每个元素被返回的概率应该与其在集合中的数量呈线性相关。
  6. +
+ +

示例:

+ +
// 初始化一个空的集合。
+RandomizedCollection collection = new RandomizedCollection();
+
+// 向集合中插入 1 。返回 true 表示集合不包含 1 。
+collection.insert(1);
+
+// 向集合中插入另一个 1 。返回 false 表示集合包含 1 。集合现在包含 [1,1] 。
+collection.insert(1);
+
+// 向集合中插入 2 ,返回 true 。集合现在包含 [1,1,2] 。
+collection.insert(2);
+
+// getRandom 应当有 2/3 的概率返回 1 ,1/3 的概率返回 2 。
+collection.getRandom();
+
+// 从集合中删除 1 ,返回 true 。集合现在包含 [1,2] 。
+collection.remove(1);
+
+// getRandom 应有相同概率返回 1 和 2 。
+collection.getRandom();
+
+ +

以下错误的选项是?

+## aop +### before +```cpp +#include +using namespace std; +``` +### after +```cpp + +``` + +## 答案 +```cpp +class RandomizedCollection +{ +public: + /** Initialize your data structure here. */ + RandomizedCollection() + { + this->num = 0; + } + + /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ + bool insert(int val) + { + this->num++; + bool res; + if (this->M.find(val) == this->M.end() || this->M[val] == 0) + { + this->M[val] = 1; + res = true; + } + else + { + this->M[val]++; + res = false; + } + return res; + } + + /** Removes a value from the collection. Returns true if the collection contained the specified element. */ + bool remove(int val) + { + if (this->M.find(val) == this->M.end() || this->M[val] == 0) + { + return false; + } + else + { + M[val]--; + this->num--; + return true; + } + } + + /** Get a random element from the collection. */ + int getRandom() + { + if (this->num > 0) + { + srand((unsigned)time(NULL)); + int randomValue = rand() % (this->num) + 1; + for (auto it : M) + { + randomValue -= it.second; + if (randomValue <= 0) + return it.first; + } + } + return 0; + } + +private: + unordered_map M; + int num; +}; +``` +## 选项 + +### A +```cpp +class RandomizedSet +{ +public: + vector nums; + unordered_map numIndex; + int size; + /** Initialize your data structure here. */ + RandomizedSet() + { + size = 0; + } + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + bool insert(int val) + { + if (numIndex.count(val) == 1) + return false; + nums.push_back(val); + numIndex[val] = size; + size++; + return true; + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + bool remove(int val) + { + if (numIndex.count(val) == 0) + return false; + int last = nums.back(); + nums[numIndex[val]] = last; + numIndex[last] = numIndex[val]; + nums.pop_back(); + numIndex.erase(val); + size--; + return true; + } + + /** Get a random element from the set. */ + int getRandom() + { + return nums[random() % size]; + } +}; +``` + +### B +```cpp +class RandomizedCollection +{ +public: + unordered_map> idx; + vector nums; + + /** Initialize your data structure here. */ + RandomizedCollection() + { + } + + /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ + bool insert(int val) + { + nums.push_back(val); + idx[val].insert(nums.size() - 1); + return idx[val].size() == 1; + } + + /** Removes a value from the collection. Returns true if the collection contained the specified element. */ + bool remove(int val) + { + if (idx.find(val) == idx.end()) + { + return false; + } + int i = *(idx[val].begin()); + nums[i] = nums.back(); + idx[val].erase(i); + idx[nums[i]].erase(nums.size() - 1); + if (i < nums.size() - 1) + { + idx[nums[i]].insert(i); + } + if (idx[val].size() == 0) + { + idx.erase(val); + } + nums.pop_back(); + return true; + } + + /** Get a random element from the collection. */ + int getRandom() + { + return nums[rand() % nums.size()]; + } +}; +``` + +### C +```cpp +class RandomizedCollection +{ +public: + vector nums; + unordered_map> numsIndex; + int size; + /** Initialize your data structure here. */ + RandomizedCollection() + { + size = 0; + } + + /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ + bool insert(int val) + { + nums.push_back(val); + numsIndex[val].insert(size); + size++; + return numsIndex[val].size() == 1; + } + + /** Removes a value from the collection. Returns true if the collection contained the specified element. */ + bool remove(int val) + { + if (numsIndex.count(val) == 0) + return false; + int last = nums.back(); + int id = size - 1; + if (last != val) + { + id = *(numsIndex[val].begin()); + numsIndex[last].erase(size - 1); + numsIndex[last].insert(id); + nums[id] = last; + } + nums.pop_back(); + size--; + numsIndex[val].erase(id); + if (numsIndex[val].empty()) + numsIndex.erase(val); + return true; + } + + /** Get a random element from the collection. */ + int getRandom() + { + return nums[random() % size]; + } +}; +``` diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/459_LFU \347\274\223\345\255\230/config.json" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/459_LFU \347\274\223\345\255\230/config.json" new file mode 100644 index 0000000000000000000000000000000000000000..70476e637da8550c6f6049536816d2fbcaf40568 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/459_LFU \347\274\223\345\255\230/config.json" @@ -0,0 +1,12 @@ +{ + "node_id": "569d5e11c4fc5de7844053d9a733c5e8", + "keywords": [ + "leetcode", + "LFU 缓存" + ], + "children": [], + "export": [ + "solution.json" + ], + "title": "LFU 缓存" +} \ No newline at end of file diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/459_LFU \347\274\223\345\255\230/desc.html" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/459_LFU \347\274\223\345\255\230/desc.html" new file mode 100644 index 0000000000000000000000000000000000000000..46cd48ce9d381b37cb5c75ec34d6cdfbe86739e1 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/459_LFU \347\274\223\345\255\230/desc.html" @@ -0,0 +1,60 @@ +

请你为 最不经常使用(LFU)缓存算法设计并实现数据结构。

+ +

实现 LFUCache 类:

+ +
    +
  • LFUCache(int capacity) - 用数据结构的容量 capacity 初始化对象
  • +
  • int get(int key) - 如果键存在于缓存中,则获取键的值,否则返回 -1。
  • +
  • void put(int key, int value) - 如果键已存在,则变更其值;如果键不存在,请插入键值对。当缓存达到其容量时,则应该在插入新项之前,使最不经常使用的项无效。在此问题中,当存在平局(即两个或更多个键具有相同使用频率)时,应该去除 最近最久未使用 的键。
  • +
+ +

注意「项的使用次数」就是自插入该项以来对其调用 getput 函数的次数之和。使用次数会在对应项被移除后置为 0 。

+ +

为了确定最不常使用的键,可以为缓存中的每个键维护一个 使用计数器 。使用计数最小的键是最久未使用的键。

+ +

当一个键首次插入到缓存中时,它的使用计数器被设置为 1 (由于 put 操作)。对缓存中的键执行 getput 操作,使用计数器的值将会递增。

+ +

 

+ +

示例:

+ +
+输入:
+["LFUCache", "put", "put", "get", "put", "get", "get", "put", "get", "get", "get"]
+[[2], [1, 1], [2, 2], [1], [3, 3], [2], [3], [4, 4], [1], [3], [4]]
+输出:
+[null, null, null, 1, null, -1, 3, null, -1, 3, 4]
+
+解释:
+// cnt(x) = 键 x 的使用计数
+// cache=[] 将显示最后一次使用的顺序(最左边的元素是最近的)
+LFUCache lFUCache = new LFUCache(2);
+lFUCache.put(1, 1);   // cache=[1,_], cnt(1)=1
+lFUCache.put(2, 2);   // cache=[2,1], cnt(2)=1, cnt(1)=1
+lFUCache.get(1);      // 返回 1
+                      // cache=[1,2], cnt(2)=1, cnt(1)=2
+lFUCache.put(3, 3);   // 去除键 2 ,因为 cnt(2)=1 ,使用计数最小
+                      // cache=[3,1], cnt(3)=1, cnt(1)=2
+lFUCache.get(2);      // 返回 -1(未找到)
+lFUCache.get(3);      // 返回 3
+                      // cache=[3,1], cnt(3)=2, cnt(1)=2
+lFUCache.put(4, 4);   // 去除键 1 ,1 和 3 的 cnt 相同,但 1 最久未使用
+                      // cache=[4,3], cnt(4)=1, cnt(3)=2
+lFUCache.get(1);      // 返回 -1(未找到)
+lFUCache.get(3);      // 返回 3
+                      // cache=[3,4], cnt(4)=1, cnt(3)=3
+lFUCache.get(4);      // 返回 4
+                      // cache=[3,4], cnt(4)=2, cnt(3)=3
+ +

 

+ +

提示:

+ +
    +
  • 0 <= capacity, key, value <= 104
  • +
  • 最多调用 105getput 方法
  • +
+ +

 

+ +

进阶:你可以为这两种操作设计时间复杂度为 O(1) 的实现吗?

diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/459_LFU \347\274\223\345\255\230/solution.cpp" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/459_LFU \347\274\223\345\255\230/solution.cpp" new file mode 100644 index 0000000000000000000000000000000000000000..3d328bb5ecdc2f09e47273eeed57e60cd0ab4ba2 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/459_LFU \347\274\223\345\255\230/solution.cpp" @@ -0,0 +1,75 @@ +#include +using namespace std; + +struct Value +{ + Value(int count_, int time_, int key_, int value_) + : count(count_), + key(key_), + value(value_), + time(time_) {} + bool operator<(const Value &a) const + { + return count == a.count ? time < a.time : count < a.count; + } + int key; + int value; + int count; + int time; +}; +class LFUCache +{ +public: + LFUCache(int capacity_) + : capacity(capacity_), + time(0) {} + + int get(int key) + { + if (capacity == 0) + return -1; + auto it = table.find(key); + if (it == table.end()) + return -1; + Value cache = it->second; + judge.erase(cache); + cache.count++; + cache.time = ++time; + judge.insert(cache); + it->second = cache; + return cache.value; + } + + void put(int key, int value) + { + if (capacity == 0) + return; + auto it = table.find(key); + if (it == table.end()) + { + if (table.size() == capacity) + { + + table.erase(judge.begin()->key); + judge.erase(judge.begin()); + } + Value put_(0, ++time, key, value); + table.insert({key, put_}); + judge.insert(put_); + } + else + { + Value temp = it->second; + judge.erase(temp); + Value put_(++temp.count, ++time, key, value); + it->second = put_; + judge.insert(put_); + } + } + +private: + const int capacity; + int time; + unordered_map table; + set judge; +}; diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/459_LFU \347\274\223\345\255\230/solution.json" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/459_LFU \347\274\223\345\255\230/solution.json" new file mode 100644 index 0000000000000000000000000000000000000000..d7bdfc6ef6b1f7e357231b21f7e6743306871bb5 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/459_LFU \347\274\223\345\255\230/solution.json" @@ -0,0 +1,6 @@ +{ + "type": "code_options", + "author": "CSDN.net", + "source": "solution.md", + "exercise_id": "4ff0bf6da5ea408a8791d86fbd62c206" +} \ No newline at end of file diff --git "a/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/459_LFU \347\274\223\345\255\230/solution.md" "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/459_LFU \347\274\223\345\255\230/solution.md" new file mode 100644 index 0000000000000000000000000000000000000000..ea06644c6f0a937c5ae90f63ef1a02b4eaf0c819 --- /dev/null +++ "b/data/3.\347\256\227\346\263\225\351\253\230\351\230\266/9.leetcode\350\256\276\350\256\241/459_LFU \347\274\223\345\255\230/solution.md" @@ -0,0 +1,392 @@ +# LFU 缓存 +

请你为 最不经常使用(LFU)缓存算法设计并实现数据结构。

+ +

实现 LFUCache 类:

+ +
    +
  • LFUCache(int capacity) - 用数据结构的容量 capacity 初始化对象
  • +
  • int get(int key) - 如果键存在于缓存中,则获取键的值,否则返回 -1。
  • +
  • void put(int key, int value) - 如果键已存在,则变更其值;如果键不存在,请插入键值对。当缓存达到其容量时,则应该在插入新项之前,使最不经常使用的项无效。在此问题中,当存在平局(即两个或更多个键具有相同使用频率)时,应该去除 最近最久未使用 的键。
  • +
+ +

注意「项的使用次数」就是自插入该项以来对其调用 getput 函数的次数之和。使用次数会在对应项被移除后置为 0 。

+ +

为了确定最不常使用的键,可以为缓存中的每个键维护一个 使用计数器 。使用计数最小的键是最久未使用的键。

+ +

当一个键首次插入到缓存中时,它的使用计数器被设置为 1 (由于 put 操作)。对缓存中的键执行 getput 操作,使用计数器的值将会递增。

+ +

 

+ +

示例:

+ +
+输入:
+["LFUCache", "put", "put", "get", "put", "get", "get", "put", "get", "get", "get"]
+[[2], [1, 1], [2, 2], [1], [3, 3], [2], [3], [4, 4], [1], [3], [4]]
+输出:
+[null, null, null, 1, null, -1, 3, null, -1, 3, 4]
+
+解释:
+// cnt(x) = 键 x 的使用计数
+// cache=[] 将显示最后一次使用的顺序(最左边的元素是最近的)
+LFUCache lFUCache = new LFUCache(2);
+lFUCache.put(1, 1);   // cache=[1,_], cnt(1)=1
+lFUCache.put(2, 2);   // cache=[2,1], cnt(2)=1, cnt(1)=1
+lFUCache.get(1);      // 返回 1
+                      // cache=[1,2], cnt(2)=1, cnt(1)=2
+lFUCache.put(3, 3);   // 去除键 2 ,因为 cnt(2)=1 ,使用计数最小
+                      // cache=[3,1], cnt(3)=1, cnt(1)=2
+lFUCache.get(2);      // 返回 -1(未找到)
+lFUCache.get(3);      // 返回 3
+                      // cache=[3,1], cnt(3)=2, cnt(1)=2
+lFUCache.put(4, 4);   // 去除键 1 ,1 和 3 的 cnt 相同,但 1 最久未使用
+                      // cache=[4,3], cnt(4)=1, cnt(3)=2
+lFUCache.get(1);      // 返回 -1(未找到)
+lFUCache.get(3);      // 返回 3
+                      // cache=[3,4], cnt(4)=1, cnt(3)=3
+lFUCache.get(4);      // 返回 4
+                      // cache=[3,4], cnt(4)=2, cnt(3)=3
+ +

 

+ +

提示:

+ +
    +
  • 0 <= capacity, key, value <= 104
  • +
  • 最多调用 105getput 方法
  • +
+ +

 

+ +

进阶:你可以为这两种操作设计时间复杂度为 O(1) 的实现吗?

+ +

以下错误的选项是?

+## aop +### before +```cpp +#include +using namespace std; +``` +### after +```cpp + +``` + +## 答案 +```cpp +class LFUCache +{ +private: + int cap; + int size; + int minfre; + unordered_map> m; + unordered_map> hash_fre; + unordered_map::iterator> hash_node; + +public: + LFUCache(int capacity) : cap(capacity), size(0) {} + + int get(int key) + { + if (m.count(key) == 0) + return -1; + + hash_fre[m[key].second].erase(hash_node[key]); + m[key].second++; + hash_fre[m[key].second].push_back(key); + hash_node[key] = --hash_fre[m[key].second].end(); + if (hash_fre[minfre].size() == 0) + { + minfre++; + } + return m[key].first; + } + + void put(int key, int value) + { + if (cap <= 0) + return; + if (get(key) != -1) + { + m[key].first = value; + return; + } + + if (size >= cap) + { + m.erase(hash_fre[minfre].front()); + hash_node.erase(hash_fre[minfre].front()); + hash_fre[minfre].pop_front(); + } + + m[key] = {value, 1}; + hash_fre[1].push_back(key); + hash_node[key] = hash_fre[1].end(); + minfre = 1; + if (size < cap) + size++; + } +}; +``` +## 选项 + +### A +```cpp +class Node +{ +public: + int cnt; + int time; + int key; + int val; + Node(int cnt, int time, int key, int val) + { + this->cnt = cnt; + this->time = time; + this->key = key; + this->val = val; + } + bool operator<(const Node &n) const + { + if (n.cnt == cnt) + return time < n.time; + return cnt < n.cnt; + } +}; +class LFUCache +{ +public: + int size; + int time; + unordered_map LFU; + set tree; + LFUCache(int capacity) + { + time = 0; + size = capacity; + } + + int get(int key) + { + if (LFU.count(key) == 0) + return -1; + unordered_map::iterator iter = LFU.find(key); + Node now = (*iter).second; + tree.erase(now); + now.cnt++; + now.time = time++; + tree.insert(now); + (*iter).second = now; + return now.val; + } + + void put(int key, int value) + { + if (LFU.count(key) == 0) + { + Node newNode = Node(1, time++, key, value); + if (size == 0) + { + if (tree.empty()) + return; + LFU.erase((*(tree.begin())).key); + tree.erase(tree.begin()); + } + else + { + size--; + } + LFU.insert(make_pair(key, newNode)); + tree.insert(newNode); + } + else + { + unordered_map::iterator iter = LFU.find(key); + Node now = (*iter).second; + tree.erase(now); + now.cnt++; + now.time = time++; + now.val = value; + tree.insert(now); + (*iter).second = now; + } + } +}; +``` + +### B +```cpp +class LFUCache +{ +public: + LFUCache(int capacity_) + : capacity(capacity_), + minfreq(0) + { + iter_table.clear(); + freq_table.clear(); + } + + int get(int key) + { + if (capacity == 0) + return -1; + auto it = iter_table.find(key); + if (it == iter_table.end()) + return -1; + list::iterator iter = it->second; + + int value = iter->value; + int freq = iter->freq; + Value new_node(key, value, freq + 1); + + freq_table[freq].erase(iter); + if (freq_table[freq].size() == 0) + { + freq_table.erase(freq); + if (minfreq == freq) + minfreq += 1; + } + freq_table[freq + 1].push_front(new_node); + iter_table[key] = freq_table[freq + 1].begin(); + return new_node.value; + } + + void put(int key, int value) + { + if (capacity == 0) + return; + auto it = iter_table.find(key); + if (it == iter_table.end()) + { + + if (iter_table.size() == capacity) + { + auto it2 = freq_table[minfreq].back(); + iter_table.erase(it2.key); + freq_table[minfreq].pop_back(); + if (freq_table[minfreq].size() == 0) + { + freq_table.erase(minfreq); + } + } + freq_table[1].push_front(Value{key, value, 1}); + iter_table[key] = freq_table[1].begin(); + minfreq = 1; + } + else + { + list::iterator iter = it->second; + + int freq = iter->freq; + Value new_node(iter->key, value, freq + 1); + + freq_table[iter->freq].erase(iter); + + if (freq_table[freq].size() == 0) + { + freq_table.erase(freq); + if (minfreq == freq) + minfreq += 1; + } + freq_table[freq + 1].push_front(new_node); + iter_table[key] = freq_table[freq + 1].begin(); + } + } + +private: + struct Value + { + Value(int key_, int value_, int freq_) + : key(key_), + value(value_), + freq(freq_) {} + int key; + int value; + int freq; + }; + int capacity; + int minfreq; + unordered_map::iterator> iter_table; + unordered_map> freq_table; +}; + +``` + +### C +```cpp +struct Value +{ + Value(int count_, int time_, int key_, int value_) + : count(count_), + key(key_), + value(value_), + time(time_) {} + bool operator<(const Value &a) const + { + return count == a.count ? time < a.time : count < a.count; + } + int key; + int value; + int count; + int time; +}; +class LFUCache +{ +public: + LFUCache(int capacity_) + : capacity(capacity_), + time(0) {} + + int get(int key) + { + if (capacity == 0) + return -1; + auto it = table.find(key); + if (it == table.end()) + return -1; + Value cache = it->second; + judge.erase(cache); + cache.count++; + cache.time = ++time; + judge.insert(cache); + it->second = cache; + return cache.value; + } + + void put(int key, int value) + { + if (capacity == 0) + return; + auto it = table.find(key); + if (it == table.end()) + { + if (table.size() == capacity) + { + + table.erase(judge.begin()->key); + judge.erase(judge.begin()); + } + Value put_(0, ++time, key, value); + table.insert({key, put_}); + judge.insert(put_); + } + else + { + Value temp = it->second; + judge.erase(temp); + Value put_(++temp.count, ++time, key, value); + it->second = put_; + judge.insert(put_); + } + } + +private: + const int capacity; + int time; + unordered_map table; + set judge; +}; + +```