leetcode之LRU Cache

来源:互联网 发布:linux history用户 编辑:程序博客网 时间:2024/04/29 17:30

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

此题需要注意几个点:

1. get(key),如果key在缓存中,则要将key所在单元设置为最近访问的状态

2. set(key,value)也是作为最近访问的单元,如果key所表示的单元已经存在缓存中,且原来的value值与该value值不相等,则要将原来的value更新为该value值

思路:

拿到此题时,首先考虑是使用数组还是使用链表作为缓存的数据结构。由于缓存经常需要对节点增删查改,如果使用数组,添加删除节点效率较低,于是决定使用链表。然后考虑是使用单链表还是使用双向链表,还是使用单向循环链表,最后决定使用双向链表,用单向循环链表也可以。

代码如下:

struct node{    int key;    int value;    struct node *next, *pre;       };struct head_ptr{    struct node *head;           int num;};class LRUCache{public:    LRUCache(int capacity) {        this->capacity = capacity;        lru_list = new head_ptr;        lru_list->head = NULL;        lru_list->num = 0;    }            int get(int key) {        if(NULL == lru_list->head) return -1;        struct node *p = lru_list->head;          do{            if(p->key == key){                //key是最后一个节点                 if(p->next == lru_list->head)                    return p->value;                //key是头节点,因为是循环链表只需将第二节点改为头节点就行                 if(p == lru_list->head){                    lru_list->head = p->next;                       return p->value;                   }                //key是链表中中间的节点                 p->pre->next = p->next;                p->next->pre = p->pre;                lru_list->head->pre->next = p;                p->pre = lru_list->head->pre;                lru_list->head->pre = p;                p->next = lru_list->head;                return p->value;                            }              p = p->next;        }while(p!=NULL && p!=lru_list->head);                  return -1;    }        void set(int key, int value) {        int res = get(key);        if(res != -1)         {            struct node *p = lru_list->head->pre;            p->value = value;            return;        }        if(lru_list->num >= capacity)        {            // cout << "key out of: " << key <<endl;             struct node *p = lru_list->head;             p->key = key;             p->value = value;             lru_list->head = p->next;               return;                       }        struct node *p = new node;            p->key = key;        p->value = value;        if(lru_list->head == NULL){            if(capacity <= 0)            {                delete p;                return;            }             p->next = p;            p->pre = p;            lru_list->head = p;                lru_list->num++;             return;               }        if(lru_list->num< capacity){           // cout << "key: " << key <<endl;            lru_list->head->pre->next = p;            p->pre = lru_list->head->pre;            lru_list->head->pre = p;            p->next = lru_list->head;            lru_list->num++;            return;                  }    }    //测试用     void printKey()    {         struct node *p = lru_list->head;         cout <<"result: ";         do{             cout << p->key << " ";              p=p->next;               }while(p && p!=lru_list->head);                  cout << endl;         }private:    int capacity;    struct head_ptr *lru_list;};



原创粉丝点击