题解 | #设计LRU缓存结构#
设计LRU缓存结构
http://www.nowcoder.com/practice/e3769a5f49894d49b871c09cadd13a61
本文仅用于本人记录
好家伙,第一次见这题,我整整弄了两小时。。。。。
一开始想着只用一个哈希表,题目的set和get都是o(1)的,可是还得处理当hashmap缓存大于k个键值对的时候清理掉最久远没set更新或者没get访问的键值对呀!所以我第一想到的就是对每个元素加一个power,代表建立该键值对的时间,越大说明越新,越小说明很久没更新/访问了。可是这样每次set和get就是o(n)了,严重超时。。。。
然后看题解,牛逼啊,用哈希表实现set和get的o(1);然后用一个链表真实存储这些数据节点(哈希表本身不创造数据节点)。这样每次操作了set或者get就将对应节点(通过哈希表可以快速o(1)地找到那个节点)挪到链表头结点后第一位去,表示最新。删除也只是要移出哈希表的那个对应节点键值对就行了,真实的节点在链表其实删不删都无所谓。
当初我还不信邪,硬是要单向链表。。。结果发现还是双向链表简洁。
import java.util.*; class Listnode{ int key; int value; Listnode next = null; Listnode prev = null; } public class Solution { /** * lru design * @param operators int整型二维数组 the ops * @param k int整型 the k * @return int整型一维数组 */ public int[] LRU (int[][] operators, int k) { // write code here HashMap<Integer,Listnode> hashMap = new HashMap<>(); Listnode head = new Listnode(); ArrayList<Integer> arrays = new ArrayList<>(); for(int i = 0;i < operators.length;i++){ if(hashMap.size() > k){ Listnode iter = head; for(int j = 0;j < k;j++){ iter = iter.next; } hashMap.remove(iter.next.key); iter.next.prev = null; iter.next = null; } if(operators[i][0] == 1){ if(hashMap.get(operators[i][1]) != null){ Listnode node = hashMap.get(operators[i][1]); node.value = operators[i][2]; hashMap.put(operators[i][1],node); moveToHead(head,node); } else{ Listnode node = new Listnode(); node.key = operators[i][1]; node.value = operators[i][2]; hashMap.put(operators[i][1],node); moveToHead(head,node); } } else if(operators[i][0] == 2){ if(hashMap.get(operators[i][1]) != null){ arrays.add(hashMap.get(operators[i][1]).value); moveToHead(head,hashMap.get(operators[i][1])); }else{ arrays.add(-1); } } } int[] result = new int[arrays.size()]; int i = 0; for (Integer array : arrays) { result[i++] = array; } return result; } void moveToHead(Listnode head,Listnode node){ if(node.next != null && node.prev != null){ node.next.prev = node.prev; node.prev.next = node.next; } if(head.next != null){ head.next.prev = node; } node.next = head.next; head.next = node; node.prev = head; } }