LRU Cache

leetcode中的LRU Cache题

网址:http://oj.leetcode.com/problems/lru-cache/

要求实现LRU Cache,及在一个容量有限的存储空间中,存放最近实用过的n组数据。

我最开始的实现方法:

public class LRUCache {
    
    Stack<Integer> stk;
    Map<Integer, Integer> map;
    int capacity, number;
    
    
    public LRUCache(int capacity) {
        this.capacity = capacity;
        number = 0;
        stk = new Stack<Integer>();
        map = new HashMap<Integer, Integer>();
    }
    
    public int get(int key) {
        if(map.containsKey(key)) {
            stk.remove((Integer)key);
            stk.push(key);
            return map.get(key);    
        }
        return -1;
    }
    
    public void set(int key, int value) {
        if(map.containsKey(key)) { //change value and change stack
            map.put(key, value);
            stk.remove((Integer)key);
            stk.push(key);
        }else {
            if(number < capacity) {    //don't need replace
                stk.push(key);
                map.put(key, value);
                number ++;
            }else {     //replace
                    //remove
                    int popKey = stk.remove(0);
                    map.remove(popKey);
                    //put
                    stk.push(key);
                    map.put(key, value);
                
            }
        }
    }
}

提交结果显示 : Time Limit Exceeded

  分析算法,capacity大小为n, 操作个数为m, get()函数的复杂度为 O(n),set()函数的复杂度为O(n)。

  由于在这个程序中,一定需要记录2种数据 (1. key对应的value; 2. 哪些key是在最近使用的n个数中),记录<key, value>对用HashMap肯定比较好,操作复杂度为O(1),记录前n个key则用双向链表,这样插入和移动比较简单,双向链表最大的缺点也就是查找复杂度为O(n), 那么可以把前面的HashMap和链表结合起来,查找时用HashMap,这样所有的复杂度就都能降到O(1)了。

然后具体的实现代码为:

public class LRUCache {
 
     class Node {
        int key;
        int val;
        Node pre, next;
        
        public Node(int key, int val) {
            this.key = key;
            this.val = val;
            this.pre = null;
            this.next = null;
        }
        
        public Node() {
            this.pre = null;
            this.next = null;
        }
        
    }
    
    
    int capacity;
    int number;
    Map<Integer, Node> map;
    Node head, last;
    
    
    public LRUCache(int capacity) {
        this.capacity = capacity;
        number = 0;
        last = null;
        head = new Node();
        map = new HashMap<Integer, Node>();
    }
    
    public int get(int key) {
        if(map.containsKey(key)) {
            Node node = map.get(key);
            int value = node.val;
            
            if(node == last) {
                if(node.pre != head) {
                    last = node.pre;
                }else {
                    //no nothing
                }
            }
            
            node.pre.next = node.next;
            if(node.next != null) {
                node.next.pre = node.pre;
            }
            
            node.next = head.next;
            if(head.next != null) {
                head.next.pre = node;
            }
            head.next = node;
            node.pre = head;

            return value;
        }
        return -1;
    }
    
    public void set(int key, int value) {
        if(map.containsKey(key)) {
            Node node = map.get(key);
            node.val = value;
            
            //deal with order
            if(node == last) {
                if(node.pre != head) {
                    last = node.pre;
                }else {
                    //no nothing
                }
            }
            
            node.pre.next = node.next;
            if(node.next != null) {
                node.next.pre = node.pre;
            }
            
            node.next = head.next;
            if(head.next != null) {
                head.next.pre = node;
            }
            head.next = node;
            node.pre = head;
        }else {
            if(number < capacity) {
                Node node = new Node(key, value);
                map.put(key, node);
                
                if(last == null) {
                    last = node;
                }
                node.next = head.next;
                node.pre = head;
                if(head.next != null) {
                    head.next.pre = node;
                }
                head.next = node;
                number ++;
            }else {
                Node node = new Node(key, value);
                node.next = head.next;
                node.pre = head;
                if(head.next != null) {
                    head.next.pre = node;
                }
                head.next = node;
                
                Node removeNode = last;
                last = last.pre;
                map.remove(removeNode.key);
                map.put(key, node);
                if(last == head) {
                    last = null;
                }
            }
        }
    }
    
}

 

 

 

 

posted @ 2014-05-28 20:20  qwertwwwe  阅读(253)  评论(0编辑  收藏  举报