题解 | #设计LRU缓存结构#

设计LRU缓存结构

http://www.nowcoder.com/practice/e3769a5f49894d49b871c09cadd13a61

这道题总体来说比较复杂。首先说一下本题主要用的思想是hashmap+双向链表。
为什么要使用hashmap,因为这样在根据key取值的时候很快,如果只有一个双向链表,那么需要遍历去找值,很麻烦。
为什么要使用双向链表,因为会不断涉及到元素的插入删除,如果单链表删除的话很麻烦。
首先就是定义一个数据结构:
static class Node{ int k,v;
    Node pre,next; public Node(int k,int v)
    { this.k = k; this.v = v;
     }
}
然后遍历输入的数组。
                int num = 0;
        int count = 0;
        for(int i=0;i<operators.length;i++){
            if(operators[i][0]==2){
                num++;
            }
        }
        int[] ret = new int[num];
        HashMap<Integer,Node> map = new HashMap<>();
        for(int i=0;i<operators.length;i++){
            if(operators[i][0]==1){
                put(map,operators[i][1],operators[i][2],k);
            }else{
                ret[count++]=get(map,operators[i][1]);
            }
        }
        return ret;
那么关键就在于插入和获取操作。
插入操作需要注意一点的是覆盖问题,如果这个元素已经了有了,那么从map中取出来,将其value值改一下即可。并且要把这个节点移动到结尾。如果这个节点本身就在结尾那么不用移动。
正常的插入就是
如下代码:
public static void put(HashMap<Integer,Node> map,int k,int v,int size){
        //覆盖没有考虑

        Node p = new Node(k,v);
        if(map.containsKey(k)){
            Node node = map.get(k);
            node.v = v;
            map.put(k,node);
            //把这个节点移动到尾部
            if(node.next!=null){
                pre.next = node;
                node.pre = pre;
                pre = node;
                head = head.next;
                head.pre=null;
                node.next = null;
            }
            return;
        }
        map.put(k,p);
        if(n==0){
            head = p;
        }
        n++;
        p.next = null;
        p.pre = pre;
        if(pre!=null){
            pre.next = p;
        }
        pre = p;
        if(map.size()>size){
            map.remove(head.k);
            head = head.next;
            head.pre = null;
        }
    }
如果这个元素就在尾部,那么不需要移动。
如果这个元素不在尾部,那么需要改变链表结构。
如果map根本就没这个元素那么直接返回-1
如果这个元素在头部那么也需要做特殊处理
public static int get(HashMap<Integer,Node> map,int k){
        if(!map.containsKey(k)){
            return -1;
        }
        Node node = map.get(k);
        if(node.pre==null){
            pre.next = node;
            node.pre = pre;
            head = node.next;
            head.pre = null;
            node.next=null;
            pre = node;
        }else if(node.next==null){
            //这个节点本身就在尾部,不需要移动
            System.out.println("1");
        }else{
            node.pre.next = node.next;
            node.next.pre = node.pre;
            pre.next = node;
            node.next = null;
            node.pre = pre;
            pre = node;
        }

        return node.v;
    }



全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务