• 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;
                    }
                }
            }
        }
        
    }
  • 相关阅读:
    Python基础(二)之数据类型和运算(6)——元组
    Python基础(二)之数据类型和运算(5)——字符串操作汇总
    Python基础(二)之数据类型和运算(4)—— 列表
    Python基础(二)之数据类型和运算(3)——其他运算算符
    Python 基础(三)——流程控制之break 、continue 、else
    Python 基础(三)之流程控制(3)——for
    Python 基础(三)之流程控制(2)——while
    Python 基础(三)之流程控制(1)——if…else
    python------迭代器与生成器
    Python基础(四)
  • 原文地址:https://www.cnblogs.com/qwertwwwe/p/3757815.html
Copyright © 2020-2023  润新知