设计LRU缓存结构--题解
设计LRU缓存结构
http://www.nowcoder.com/questionTerminal/e3769a5f49894d49b871c09cadd13a61
写在前面
本题是看着大佬的代码写的,讲讲大佬的思路
https://www.nowcoder.com/profile/797566439
解法
样例 [[1,1,1],[1,2,2],[1,3,2],[2,1],[1,4,4],[2,2]],3
第一个数字 1 代表 set方法, 2 代表 get方法
第二个第三个 代表 key value
最后一个数字是 k 代表长度 只能容纳多少个key value。
输入的是 每次get的值。 如果找不到就是-1;
本质上还是运用双向链表实现 LRU ,HashMap 只是为了更快的查询到key
当我们遇到第一个set方法的时候 就需要插入到head 和tail 之间,
每次插入都放在head的后面 因为是最近最少使用嘛,你使用了就放在头结点后面就可以了。最后是这样的链表。
当我们遇到get的时候,就把需要被get的结点 给移除,然后放在头结点。
遇到需要自动移除结点的时候,就把这个结点移除就OK了,然后新放入的结点还是放在head的后面。
代码
import java.util.*; public class Solution { static class Node{ int key , value; Node prev,next; public Node(int key , int value){ this.key = key; this.value = value; } } private Map<Integer,Node> map = new HashMap<>(); private Node head = new Node(-1,-1); private Node tail = new Node(-1,-1); private int k; public int[] LRU (int[][] operators, int k) { // write code here this.k = k; head.next = tail; tail.prev = head; int len =(int) Arrays.stream(operators).filter(x->x[0] == 2).count(); int[] ans = new int[len]; int cnt = 0; for(int i=0;i < operators.length ;i++){ if(operators[i][0] == 1){ set(operators[i][1],operators[i][2]); }else{ ans[cnt++] = get(operators[i][1]); } } return ans; } public void set(int key,int value){ if(get(key) > -1){ map.get(key).value = value; }else{ if(map.size() == k ){ int rk = tail.prev.key; tail.prev.prev.next = tail; tail.prev = tail.prev.prev; map.remove(rk); } Node node = new Node(key,value); map.put(key,node); removeToHead(node); } } public int get(int key){ if(map.containsKey(key)){ Node node = map.get(key); node.prev.next = node.next; node.next.prev = node.prev; removeToHead(node); return node.value; } return -1; } public void removeToHead(Node node){ node.next = head.next; head.next.prev = node; head.next = node; node.prev = head; } }