首页 > 系统服务 > 详细

LeetCode LRU Cache

时间:2015-11-04 10:05:24      阅读:263      评论:0      收藏:0      [点我收藏+]

原题链接在这里:https://leetcode.com/problems/lru-cache/

可以通过HashMap 和 Double LinkedList来完成。每个key, value用一个Node 来储存,按照添加顺序一个一个放在list 的head后面。同时把<key, node>放在HashMap中。

get时看HashMap中是否有这个key, 有的话就找到对应的node, 在node里取出对应的value. 同时更新该node 在list中的位置。

set时分三种情况:1. 看HashMap中是否有这个key, 有的话说明本来就有这个key对应的node, 只需要把原有node的value更改并且更新该node 在list中位置即可。

2. HashMap中没有这个key, 同时HashMap的size未达到capacity, 那么新建一个node, 加入HashMap 和 list中即可。

3. HashMap中没有这个key, 同时HashMap的size已经等于capacity, 多加就要招标了,所以按照2中完成添加后要从HashMap 和 list中都去掉最老的node.

AC Java:

class Node{
    Node prev;
    Node next;
    int key;
    int value;
    Node(int key, int value){
        this.key = key;
        this.value = value;
    }
}

public class LRUCache {
    Node head;
    Node tail;
    int capacity;
    HashMap<Integer, Node> hm;
    
    public LRUCache(int capacity) {
        head = new Node(-1,-1);
        tail = new Node(1,1);
        head.next = tail;
        tail.prev = head;
        this.capacity = capacity;
        hm = new HashMap<Integer, Node>();
    }
    
    public int get(int key) {
        if(hm.containsKey(key)){
            Node p = hm.get(key); //error
            putToHead(p);   //put p to the newest position of list
            return p.value;
        }
        return -1;
    }
    
    public void set(int key, int value) {
        if(hm.containsKey(key)){
            Node p = hm.get(key);
            p.value = value;
            putToHead(p);   //update p‘s position in the list
        }else if(hm.size() < capacity){
            Node p = new Node(key, value);
            hm.put(key,p);
            putToHead(p);
        }else{
            Node p = new Node(key,value);
            hm.put(key,p);
            putToHead(p);
            int oldKey = removeOldest();    //remove oldest node from the list
            hm.remove(oldKey);  //remove oldest node from hashmap
        }
    }
    
    private void putToHead(Node p){
        if(p.prev != null && p.next != null){
            p.prev.next = p.next;
            p.next.prev = p.prev;
        }
        p.prev = head;
        p.next = head.next;
        head.next.prev = p;
        head.next = p;
    }
    
    private int removeOldest(){
        Node oldest = tail.prev;
        int oldKey = oldest.key;
        oldest.prev.next = tail;
        tail.prev = oldest.prev;
        return oldKey;
    }
}

另一种方法是用LinkedHashMap, 这种数据结构本身已经把HashMap按照添加顺序放好了。

可以参见这个网页:http://www.tutorialspoint.com/java/java_linkedhashmap_class.htm 

所以实现起来很简洁,get时需要更新位置,更新位置是通过删掉旧的,复制一下加回去。

set时参照上面的三种情况即可。

AC Java:

import java.util.LinkedHashMap;
public class LRUCache {
    LinkedHashMap<Integer, Integer> linkedHM;
    int capacity;
    public LRUCache(int capacity) {
        linkedHM = new LinkedHashMap<Integer, Integer>();
        this.capacity = capacity;
    }
    
    public int get(int key) {
        if(linkedHM.containsKey(key)){
            int val = linkedHM.get(key);
            linkedHM.remove(key);
            linkedHM.put(key,val);
            return val;
        }
        return -1;
    }
    
    public void set(int key, int value) {
        if(linkedHM.containsKey(key)){
            linkedHM.remove(key);
            linkedHM.put(key,value);
        }else if(linkedHM.size() < capacity){
            linkedHM.put(key,value);
        }else{
            int oldKey = linkedHM.keySet().iterator().next();
            linkedHM.remove(oldKey);
            linkedHM.put(key,value);
        }
    }
}

LeetCode LRU Cache

原文:http://www.cnblogs.com/Dylan-Java-NYC/p/4935048.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!