From 9cfdae328b940610ce7aabbca6ca54eed8b26a06 Mon Sep 17 00:00:00 2001 From: aucker Date: Thu, 22 Aug 2024 09:05:19 +0800 Subject: [PATCH] Aug22: bit ops, revisit LRU [M] LRU and LFU cache, listnode ops --- daily/Aug22.cc | 105 ++++++++++++++++++ ...mber-of-ways-to-divide-a-long-corridor.cpp | 3 +- 2 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 daily/Aug22.cc diff --git a/daily/Aug22.cc b/daily/Aug22.cc new file mode 100644 index 0000000..79fcbc3 --- /dev/null +++ b/daily/Aug22.cc @@ -0,0 +1,105 @@ +#include +using namespace std; + +class Solution { + public: + /** + * @brief LC3133: Min Array End [M][Bit ops] + * Time: O(logx + logn), Space: O(1) + * + * @param n + * @param x + * @return long long + */ + long long midEnd(int n, int x) { + n--; // n - 1 + long long ans = x; + int i = 0, j = 0; + while (n >> j) { + // i-th bit of x is 0 + if ((ans >> i & 1) == 0) { + // j-th bit of n + ans |= (long long)(n >> j & 1) << i; + j++; + } + i++; + } + return ans; + } +}; + +/** + * @brief LRU Cache + * + */ +struct Node { + int key, val; + Node *prev, *next; + Node() : key(0), val(0), prev(nullptr), next(nullptr) {} + Node(int key_, int val_) + : key(key_), val(val_), prev(nullptr), next(nullptr) {} +}; + +class LRUCache { + private: + unordered_map cache; + Node* head; + Node* tail; + int size; + + public: + LRUCache(int capacity_) : size(capacity_) { + head = new Node(); + tail = new Node(); + head->next = tail; + tail->prev = head; + } + + void deleteNode(Node* node) { + node->next->prev = node->prev; + node->prev->next = node->next; + } + + void addHead(Node* node) { + node->next = head->next; + node->prev = head->next->prev; + head->next->prev = node; + head->next = node; + } + + void popTail() { + Node* node = tail->prev; + deleteNode(node); + cache.erase(node->key); + } + + int get(int key) { + int res = -1; + if (cache.find(key) != cache.end()) { + Node* node = cache[key]; + res = node->val; + deleteNode(node); + addHead(node); + } + return res; + } + + void put(int key, int value) { + if (size == 0) return; + // check if key exists + if (get(key) != -1) { + // exist + Node* node = cache[key]; + node->val = value; + deleteNode(node); + addHead(node); + } else { + if (size == cache.size()) { + popTail(); + } + Node* node = new Node(key, value); + cache[key] = node; + addHead(node); + } + } +}; diff --git a/daily/cpp/Nov-28-Number-of-ways-to-divide-a-long-corridor.cpp b/daily/cpp/Nov-28-Number-of-ways-to-divide-a-long-corridor.cpp index 92f16b5..290ca29 100644 --- a/daily/cpp/Nov-28-Number-of-ways-to-divide-a-long-corridor.cpp +++ b/daily/cpp/Nov-28-Number-of-ways-to-divide-a-long-corridor.cpp @@ -11,8 +11,7 @@ class Solution { if (corridor[i] == 'S') { chairs++; - while (++i < corridor.size() && corridor[i] != 'S') - ; + while (++i < corridor.size() && corridor[i] != 'S'); // the while increment i and check each character in the corridor // string. the loop continues until the end of the string or until the // next chair.