146. LRU Cache

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.

 

 

http://blog.csdn.net/dazhi_100/article/details/44201051

http://gogole.iteye.com/blog/692103

可以用Java自带的LinkedHashMap,重写removeEldestEntry方法实现触发删除最不常用的条件,在构造器的第三个参数设置为true实现按照最不常用的方式排序

 

public class LRUCache {
    
	LinkedHashMap<Integer, Integer> map;
	int capacity;
	
    public CopyOfLRUCache(int capacity) {
    	
    	this.capacity = capacity;
    	
    	map = new LinkedHashMap<Integer, Integer>(256, 0.75f, true){
			private static final long serialVersionUID = 1L;
			@Override
			protected boolean removeEldestEntry(Entry<Integer, Integer> eldest) {
				return size() > CopyOfLRUCache.this.capacity;
			}
    	};
    }
    
    public int get(int key) {
        return map.containsKey(key) ? map.get(key) : -1;
    }
    
    public void set(int key, int value) {
        map.put(key, value);
    }
}

 

 

 

 

 

在网上看了一下,可以用HashMap + 双向链表 实现。在Discuss看到有个大神级的答案:

 

 

The problem can be solved with a hashtable that keeps track of the keys and its values in the double linked list. One interesting property about double linked list is that the node can remove itself without other reference. In addition, it takes constant time to add and remove nodes from the head or tail.

One particularity about the double linked list that I implemented is that I create a pseudo head and tail to mark the boundary, so that we don't need to check the NULL node during the update. This makes the code more concise and clean, and also it is good for the performance as well.

 

 

 

 

import java.util.HashMap;

class DLinkedNode {
	int key, value;
	DLinkedNode pre, post;
}

public class LRUCache {
	
	HashMap<Integer, DLinkedNode> cache = new HashMap<Integer, DLinkedNode>();
	int capacity;
	DLinkedNode head, tail;
	
    
	// Always add the new node right after head;
	private void addNode(DLinkedNode node) {
		node.pre = head;
		node.post = head.post;
		
		head.post.pre = node;
		head.post = node;
	}
	
	// Remove an existing node from the linked list.
	private void removeNode(DLinkedNode node) {
		DLinkedNode pre = node.pre;
		DLinkedNode post = node.post;
		
		pre.post = post;
		post.pre = pre;
	}
	
	// Move certain node in between to the head.
	private void moveToHead(DLinkedNode node) {
		this.removeNode(node);
		this.addNode(node);
	}
	
	// pop the current tail. 
	private DLinkedNode popTail() {
		DLinkedNode res = tail.pre;
		removeNode(res);
		return res;
	}
	
	
    public LRUCache(int capacity) {
    	
    	this.capacity = capacity;
    	
    	head = new DLinkedNode();
    	tail = new DLinkedNode();
    	
    	head.post = tail;
    	tail.pre = head;
    	
    	head.pre = null;
    	tail.post = null;
    }
    
    public int get(int key) {
        if(!cache.containsKey(key))	return -1;
        
        DLinkedNode node = cache.get(key);
        moveToHead(node);
        return node.value;
    }
    
    public void set(int key, int value) {
        if(cache.containsKey(key)) {
        	DLinkedNode target = cache.get(key);
        	target.value = value;
        	
        	moveToHead(target);
        	
        } else {
        	if(cache.size() == capacity) {
        		DLinkedNode tail = popTail();
        		cache.remove(tail.key);
        	}
        	
        	DLinkedNode newNode = new DLinkedNode();
        	newNode.key = key;
        	newNode.value = value;
        	cache.put(key, newNode);
        	
        	addNode(newNode);
        }
    }
}

 

 

 

 

 

 

用Python

1. OrderedDict应该内置了双端队列的实现

2. OrderedDict.popitem(last=True)

from collections import OrderedDict

class LRUCache(object):

    def __init__(self, capacity):
        """
        :type capacity: int
        """
        self.d = OrderedDict()
        self.capacity = capacity

    def get(self, key):
        """
        :type key: int
        :rtype: int
        """
        if key not in self.d: return -1
        val = self.d[key]
        del self.d[key]
        self.d[key]=val
        return val
        

    def put(self, key, value):
        """
        :type key: int
        :type value: int
        :rtype: void
        """
        if key in self.d: del self.d[key]
        if len(self.d)==self.capacity:
            self.d.popitem(False)
        self.d[key]=value
        
        


# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值