460. LFU Cache

typedef struct my_val my_val_t;
struct my_val {
int     key;
int     val;
int     frequency;
my_val_t* next;
my_val_t* pre;
my_val(int k, int v) { key = k;val = v;frequency = 1;next = NULL;pre = NULL; };
};
class LFUCache {
public:
LFUCache(int capacity) {
m_cap = capacity;
}


int get(int key) {
if (m_node.count(key))
{
my_val_t* p = m_node[key];
int fr = p->frequency;
int ans = p->val;
// get off the node from original frequency
my_val_t* head = m_fr[fr];
getoffNode(p);


//the original changed to empty , erase this frequency.
if (head->next == head)
{delete head;head = NULL;m_fr.erase(fr);}// insert the  the node to the new frequencyp->frequency = ++fr;// if the new frequency not emptyif (m_fr.count(fr)){my_val_t* headNew = m_fr[fr];insertNodeTofirst(headNew, p);}else{m_fr[fr] = insertNodeTofirst(NULL, p);}return ans;}else{return -1;}}void put(int key, int value) {int ret = get(key);if (ret != -1){m_node[key]->val = value;return;}if (0 == m_cap){return;







































};my_val_t* p = new my_val_t(key,value);if (m_node.size()<m_cap){int fr = p->frequency;if (m_fr.count(fr)){my_val_t* headNew = m_fr[fr];insertNodeTofirst(headNew, p);}else{m_fr[fr] = insertNodeTofirst(NULL, p);}}else{// find the min frenquency listmy_val_t* pHead = (*(m_fr.begin())).second;// get rid of the last node;my_val_t* pFree = pHead->pre;getoffNode(pHead->pre);// free pHead->pre// get rid of pHead->pre from m_nodeif (pHead->pre == pHead){delete pHead;pHead = NULL;





























m_fr.erase(m_fr.begin());
}
m_node.erase(pFree->key);delete pFree;pFree = NULL;int fr = p->frequency;if (m_fr.count(fr)){my_val_t* headNew = m_fr[fr];insertNodeTofirst(headNew, p);}else{m_fr[fr] = insertNodeTofirst(NULL, p);}}m_node[key] = p;}private:unordered_map<int, my_val_t*>    m_node;  // map nodemap<int, my_val_t*>              m_fr;    // map frenquencyint                             m_cap;   // capacityprivate:void getoffNode(my_val_t* p){p->pre->next = p->next;p->next->pre = p->pre;


























};
my_val_t* insertNodeTofirst(my_val_t* head, my_val_t* p)
{
if (head == NULL)
{head = new my_val_t(0,0);head->next = head;head->pre = head;}p->next = head->next;head->next->pre = p;head->next = p;p->pre = head;return head;}};











Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326229915&siteId=291194637