LRU leetcode 代码实现

12 篇文章 0 订阅
1 篇文章 0 订阅



最近在刷leetcode上面的题目,尝试做了一下LRU的题目,我自己明明能跑得通的程序放在leetcode上面测试会出现Runtime time Error, 而且测试样例也不大,完全不可能超时呀!!!肿么会有这种情况

再加上我借鉴了: http://blog.csdn.net/hexinuaa/article/details/6630384 上面的方法,按理说时间复杂度已经降到低


那位大神能帮我看一下代码,还是我忘记了了leetcode的一些规范:


#include <iostream>

using namespace std;
struct biNode{
    biNode *next;
    biNode *prev;
    struct lkNode* p_lkNode;
    int value;
    biNode(){next=NULL;prev=NULL;p_lkNode=NULL;value=0;}
};

struct lkNode{
    lkNode *next;
    biNode *p_biNode;
    int data;
    lkNode(){next=NULL;p_biNode=NULL;data=0;}
};

class LRUCache{
private:
    int used,cap;
    struct lkNode** hash_kNode;
    struct biNode* p_hdNode;
    inline int hash_fn(int key,int capacity){return (key%capacity);}
public:
    LRUCache(int capacity) {
        cap = capacity;
        hash_kNode = new lkNode*[capacity];  // check if every member point to NULL
        // try it, if not initial to NULL, will it be tested with memory leakage.
        for (int i=0;i<capacity;i++){
            hash_kNode[i] = NULL;
        }
        p_hdNode = new struct biNode;
        p_hdNode->next = NULL;
        p_hdNode->prev = NULL;
        used = 0;
    }

    int get(int key) {
        int ret;
        int h_key = hash_fn(key,cap);
        if (hash_kNode[h_key] == NULL) return -1;
        else{
            //cout<<hash_kNode[h_key]->data;
            lkNode* tmp_scan = hash_kNode[h_key];
            while(tmp_scan!=NULL){
                if (tmp_scan->data != key){
                    tmp_scan = tmp_scan->next;
                    continue;
                }
                else{
                    biNode* tmp_mthbiNode = tmp_scan->p_biNode;
                    ret = tmp_mthbiNode ->value;
                    biNode* tmp_hdnext = p_hdNode->next;
                    biNode* tmp_hdprev = p_hdNode->prev;
                    biNode* tmp_fdnext = tmp_mthbiNode->next;
                    biNode* tmp_fdprev = tmp_mthbiNode->prev;
                    p_hdNode->next = tmp_mthbiNode;
                    tmp_mthbiNode->prev = tmp_hdprev;
                    tmp_mthbiNode->next = tmp_hdnext;
                    tmp_hdprev->next = tmp_mthbiNode;
                    tmp_hdnext->prev = tmp_mthbiNode;
                    tmp_fdprev->next = tmp_fdnext;
                    tmp_fdnext->prev = tmp_fdprev;
                    return ret;
                }
            }
        }
        return -1;
    }

    void set(int key, int value) {
        int h_key = hash_fn(key,cap);
        lkNode* tmp_scan = hash_kNode[h_key];
        lkNode* tmp_scanBak=NULL;
        while(tmp_scan!=NULL){
            tmp_scanBak = tmp_scan;
            tmp_scan = tmp_scan->next;
        }
        // create new lkNode(and init) and corresponding biNode
        lkNode* new_lkNode= new struct lkNode;

        if (tmp_scanBak != NULL)
        tmp_scanBak->next = new_lkNode;
        else{
            hash_kNode[h_key] = new_lkNode;
        }

        biNode* new_biNode = new struct biNode;
        new_lkNode->p_biNode = new_biNode;
        new_lkNode->next = NULL;
        new_lkNode->data = key;
        new_biNode->value = value;
        new_biNode->p_lkNode = new_lkNode;
        new_biNode->next = new_biNode; // in order to deal with first insert scenario
        new_biNode->prev = new_biNode;

        if (used == cap){
            //first delete tail biNode (find lkNode first, otherwise it cannot be pointed!)
            biNode* del_biNode = p_hdNode->prev;
            lkNode* del_lkNode = del_biNode->p_lkNode;
            int del_key = del_lkNode->data;
            int h_delKey = hash_fn(del_key,cap);

            biNode* tmp_tlprev = del_biNode->prev;
            biNode* tmp_tlnext = del_biNode->next;
            p_hdNode->prev = tmp_tlprev;
            tmp_tlprev->next = tmp_tlnext;
            tmp_tlnext->prev = tmp_tlprev;
            delete del_biNode;
            del_biNode = NULL;

            //then delete corresponding lkNode
            tmp_scan = hash_kNode[h_delKey];
            tmp_scanBak = tmp_scan;
            int flag = 0;
            while(tmp_scan->data!=del_key){
                flag = 1;
                tmp_scanBak = tmp_scan;
                tmp_scan = tmp_scan->next;
            }
            if (flag == 1){
                flag = 0;
                tmp_scanBak->next = tmp_scan->next;
            }
            else
            hash_kNode[h_delKey] = tmp_scan->next;

            delete tmp_scan;
            tmp_scan = NULL;
            used--;

        }

        //insert new biNode to head (and link lk_Node)
        if (p_hdNode->next == NULL && p_hdNode->prev == NULL){
            p_hdNode->next = new_biNode;
            p_hdNode->prev = new_biNode;
        }
        else{
            biNode* tmp_hdnext = p_hdNode->next;
            biNode* tmp_hdprev = p_hdNode->prev;
            p_hdNode->next = new_biNode;
            new_biNode->prev = tmp_hdprev;
            new_biNode->next = tmp_hdnext;
            tmp_hdnext->prev = new_biNode;
            tmp_hdprev->next = new_biNode;
        }

        //cout<<hash_kNode[h_key]->data;

        // used one point;
        used ++;

    }
};

int main()
{
    LRUCache lru(1);
    lru.set(2,1);
    cout<<lru.get(2);
    lru.set(3,2);
    cout<<lru.get(2);
    cout<<lru.get(3);
    return 0;
}

不剩感激,我的输出是1,-1,2,应该没错吧!

难道我理解的LRU有错???疑问

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是Python语言实现LRU算法代码: ```python class LRUCache: def __init__(self, capacity: int): self.capacity = capacity self.hash = {} self.head = DoublyLinkedListNode() self.tail = DoublyLinkedListNode() self.head.next = self.tail self.tail.prev = self.head def get(self, key: int) -> int: node = self.hash.get(key, None) if not node: return -1 self._move_to_head(node) return node.value def put(self, key: int, value: int) -> None: node = self.hash.get(key) if not node: node = DoublyLinkedListNode(key=key, value=value) self.hash[key] = node self._add_to_head(node) if len(self.hash) > self.capacity: tail = self._pop_tail() del self.hash[tail.key] else: node.value = value self._move_to_head(node) def _add_to_head(self, node): node.prev = self.head node.next = self.head.next self.head.next.prev = node self.head.next = node def _remove_node(self, node): node.prev.next = node.next node.next.prev = node.prev def _move_to_head(self, node): self._remove_node(node) self._add_to_head(node) def _pop_tail(self): tail = self.tail.prev self._remove_node(tail) return tail class DoublyLinkedListNode: def __init__(self, key=None, value=None): self.key = key self.value = value self.prev = None self.next = None ``` 该代码模拟了一个双向链表来实现LRU,主要的操作包括get、put、_add_to_head、_remove_node、_move_to_head和_pop_tail,其中_put_to_head用于将一个节点添加到链表的头部,_remove_node用于移除一个节点,_move_to_head用于把链表中的某一个节点移到链表的头部,_pop_tail用于移除链表的尾节点。LRUCache类则是通过调用这些方法来实现LRU缓存。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值