leetCode:146 和 面试题 16.25. LRU Cache LCCI

problem

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.
get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
put(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.
The cache is initialized with a positive capacity.

solution

思考过程
这个就是操作系统中对进程的一种调度算法,不过这里时简化版本,行的
最近最少使用就是当capacity 满了过后,清理掉的数据应该是最没有被使用过的
其中get操作就更新了被get的数据的时间长度变成了最新被使用的
既然这样的话,两个想法:(最好不要用背后的库,这里最好自己设计才能体现一种最原始的思想吧

第一,用一种数据结构,索引为第一个或是最后一个的就是最新最近使用的,get过后,都要把相应的数据放到相应的位置表明是最新的,达到容量过后,就删掉相反的端的位置
用hash表来存储,因为key的唯一性和便于查找,用链表来更改数据的位置 ,底层的实现。
每次在插入的时候都要遍历链表,
很不方便呀,再开辟一个空间存key值,针对python和java,应该是不一样的
在数组里面实现链表,而且也要方便调换,我的python语法功底不行呀
看了LeetCode大佬的解题,机智呀,,你要找到目前链表的前后结构所在,双向链表
原来put已有的key值,就是更新原理啊的值,也算对这个值的访问,要放到头队列
第二,给每一个数据来一个时间索引,细想好像不太好,每次都要调整

方法

代码

Java

class LRUCache {
    private class TreeNode{
        int key=0;
        int value=0;
        TreeNode pre=null;
        TreeNode next=null;
        public TreeNode(){

        }
    }
    private int size = 0;
    private int capacity = 0;
    private TreeNode head = new TreeNode();
    HashMap<Integer, TreeNode> hashmap = new HashMap<>();

    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.head.next = this.head;
        this.head.pre = this.head;
    }

public void putanewone(TreeNode node){
        node.next=head.next;
        node.pre=head;
        head.next=node;
        node.next.pre=node;
}
    public void movetofirst(TreeNode node){
        node.pre.next=node.next;
        node.next.pre=node.pre;
        putanewone(node);
    }
    public int get(int key) {
        if (hashmap.containsKey(key)){
            movetofirst(hashmap.get(key));
            return hashmap.get(key).value;
        }
        return -1;
    }
    public void put(int key, int value) {
        if (hashmap.containsKey(key)){
            hashmap.get(key).value=value;
            movetofirst(hashmap.get(key));
        }
        else if(size<capacity){
            TreeNode node=new TreeNode();
            node.key=key;
            node.value=value;
            hashmap.put(key,node);
            size++;
            putanewone(node);

        }
        else{
            head.key=key;
            head.value=value;
            hashmap.put(key,head);
            head=head.pre;
            hashmap.remove(head.key);
        }

    }
}

python

class Node:
    def __init__(self, value=None):
        self.value = value
        # 以为这个key可以不用的,但是后面为了节省开销,不得不用哎
        self.key = None
        self.pre = None
        self.next = None


class LRUCache:

    def __init__(self, capacity: int):
        self.hashmap = {}
        self.size = 0
        self.capacity = capacity
        # 构成一个环,而不用尾节点
        self.head = Node()
        self.head.pre = self.head
        self.head.next = self.head

    def putanewone(self, node) -> None:
        node.next = self.head.next
        node.pre = self.head
        node.next.pre = node
        self.head.next = node

    def movetofirst(self, node) -> None:
        # 要把原来的位置给衔接上
        node.pre.next = node.next
        node.next.pre = node.pre
        self.putanewone(node)


    def get(self, key: int) -> int:
        if key in self.hashmap:
            # 让head的next指向该节点
            self.movetofirst(self.hashmap[key])
            return self.hashmap[key].value
        return -1

    def put(self, key: int, value: int) -> None:
        if key in self.hashmap:
            self.hashmap[key].value = value
            # 传入节点的位置好更改
            # 让head的next指向该节点
            self.movetofirst(self.hashmap[key])
        # 如果容量满了,可不可以直接替换掉尾巴那个,而不创建新的node呢?
        elif self.size < self.capacity:
            node = Node(value)
            node.key=key
            self.hashmap[key] = node
            # size的容量加1
            self.size += 1
            self.putanewone(node)
        else:
            # 你也许可以直接把头节点的位置和尾节点位置调换,把新的值给head,别忘记更改原来的hashmap
            self.head.key=key
            self.head.value=value
            self.hashmap[key]=self.head
            self.head=self.head.pre
            del self.hashmap[self.head.key]
总结
  • hsahmap和双向链表的两种数据结构的结合使用可以很好的避免数组和链表的不足,完成在查找和增删的结合使用
  • 代码果然是错一个字都不行呀,就是一个if和elif 的区别,我找代码的bug找了至少两小时╥﹏╥…
  • 短时间内写出无bug的代码还是得多多练习,向来都是自己逻辑错误和敲代码手误
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值