• LeetCode解题报告: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.

    思路:Java的LinkedHashMap可以实现最近最少使用(LRU)的次序。类似于HashMap。详见《JAVA编程思想(第4版)》P487.

             题目要求是一个固定大小的cache,因此需要一个变量maxCapacity来记录容量大小,用LinkedHashMap存储数据。在添加数据set()方法时,判断一下是否达到maxCapacity,如果cache已经满了,remove掉最长时间不使用的数据,然后put进新的数据。

    注意:HashMap,LinkedHashMap,TreeMap的区别,详细看看StackOverFlow

    LinkedHashMap最常用的是LRU cache的实现。
    如果用C++实现的话, hashmap + 双向链表:用 双向链表记录value 用hashmap记录 key值在链表中的位置(指针)。

    unordered_map<int, list<CacheNode>:: iterator> cacheMap;

    题解:

    import java.util.LinkedHashMap;
    
    public class LRUCache {
    
    	LinkedHashMap<Integer, Integer> linkedmap;
    	int maxCapacity;
    
    	public LRUCache(int capacity) {
    		this.maxCapacity = capacity;
    		this.linkedmap = new LinkedHashMap<Integer, Integer>(capacity, 1f, true);
    	}
    
    	public int get(int key) {
    		if (linkedmap.containsKey(key))
    			return linkedmap.get(key);
    		else
    			return -1;
    	}
    
    	public void set(int key, int value) {
    		int size = linkedmap.size();
    		if ((size < maxCapacity) || (linkedmap.containsKey(key))) {
    			linkedmap.put(key, value);
    		} else if (size >= maxCapacity) {
    			Iterator<Integer> it = linkedmap.keySet().iterator();//iterator method is superior the toArray(T[] a) method.
    			linkedmap.remove(it.next());
    			linkedmap.put(key, value);
    		}
    	}
    }
    

    结题遇到的问题:

    1.下面这段代码提交的时候超时了。

    import java.util.LinkedHashMap;
    
    public class LRUCache {
    	LinkedHashMap<Integer, Integer> linkedmap;
    	int maxCapacity;
    
    	public LRUCache(int capacity) {
    		this.maxCapacity = capacity;
    		this.linkedmap = new LinkedHashMap<Integer, Integer>(capacity, 1f, true);
    	}
    
    	public int get(int key) {
    		if (linkedmap.containsKey(key))
    			return linkedmap.get(key);
    		else
    			return -1;
    	}
    
    	public void set(int key, int value) {
    		int size = linkedmap.size();
    		if ((size < maxCapacity) || (linkedmap.containsKey(key))) {
    			linkedmap.put(key, value);
    		} else if (size >= maxCapacity) {
    			Integer[] keyArray = linkedmap.keySet().toArray(new Integer[0]);//这是超时的代码,采用Iterator不会超时。
    			linkedmap.remove(keyArray[0]);
    			linkedmap.put(key, value);
    		}
    	}
    
    }
    

    2.Roger自己实现LinkedHashMap的功能,采用双向链表和哈希表。效率略低于LinkedHashMap.(644ms>548ms)  

    import java.util.HashMap;
    
    public class LRUCache {
    
    	private HashMap<Integer, Entry<Integer>> index;
    	private UDFList<Integer> data;
    
    	public LRUCache(int capacity) {
    		index = new HashMap<Integer, Entry<Integer>>(capacity);
    		data = new UDFList<Integer>(capacity);
    	}
    
    	public int get(int key) {
    		if (!isExist(key)) {
    			index.remove(key);
    			return -1;
    		}
    		if (!index.get(key).equals(data.head)) {
    			Entry<Integer> nodePtr = data.adjust(index.get(key));
    			index.put(key, nodePtr);
    		}
    		return index.get(key).element;
    	}
    
    	public void set(int key, int value) {
    		if (isExist(key)) {
    			data.remove(index.get(key));
    		}
    		index.put(key, data.push(value));
    	}
    
    	private boolean isExist(int key) {
    		if (index.get(key) == null) {
    			return false;
    		}
    		if (index.get(key).element == null) {
    			return false;
    		}
    		return true;
    	}
    
    	public class UDFList<E> {
    		public Entry<E> head;
    		public Entry<E> tail;
    		public final int size;
    		public int length = 0;
    
    		public UDFList(int size) {
    			head = new Entry<E>(null, null, null);
    			tail = head;
    			this.size = size;
    		}
    
    		public Entry<E> adjust(Entry<E> node) {
    			if (node.equals(tail)) {
    				tail = tail.previous;
    				tail.next = null;
    				node.previous = null;
    			} else if (node.equals(head)) {
    				node = null;
    				return head;
    			} else {
    				node.previous.next = node.next;
    				node.next.previous = node.previous;
    			}
    			head.previous = node;
    			node.next = head;
    			head = node;
    			node = null;
    			return head;
    		}
    
    		public Entry<E> push(E e) {
    			Entry<E> newNode = new Entry<E>(e, null, null);
    			if (length == 0) {
    				head = newNode;
    				tail = head;
    			} else {
    				head.previous = newNode;
    				newNode.next = head;
    				head = newNode;
    			}
    			if (length == size) {
    				remove(tail);
    			}
    			length++;
    			return head;
    		}
    
    		public void remove(Entry<E> node) {
    			if (node == null)
    				return;
    			node.element = null;
    			if (node.equals(head)) {
    				head = head.next;
    			} else if (node.equals(tail)) {
    				tail = tail.previous;
    				tail.next = null;
    			} else {
    				node.previous.next = node.next;
    				node.next.previous = node.previous;
    			}
    			node = null;
    			length--;
    		}
    	}
    
    	public class Entry<E> {
    		public E element;
    		public Entry<E> previous;
    		public Entry<E> next;
    
    		public Entry(E element, Entry<E> next, Entry<E> previous) {
    			this.element = element;
    			this.next = next;
    			this.previous = previous;
    		}
    	}
    }
    

      

      

  • 相关阅读:
    (转)js的左右滑动触屏事件
    (转)Document对象内容集合
    AppCan相关网站
    (转)iOS应用程序生命周期(前后台切换,应用的各种状态)详解
    (转)深入浅出 iOS 之生命周期
    (转)iphone数据存储之-- Core Data的使用
    (转)xcode5.0.2下国际化图文解说
    (转)IOS之Info.plist文件简介
    Note_Master-Detail Application(iOS template)_06_ YJYDetailViewController.h
    Note_Master-Detail Application(iOS template)_07_ YJYDetailViewController.m
  • 原文地址:https://www.cnblogs.com/byrhuangqiang/p/3786105.html
Copyright © 2020-2023  润新知