NC93 & LeetCode 146. LRU 缓存
import java.util.*; public class Solution { public int[] LRU (int[][] operators, int k) { // write code here Listlist = new ArrayList<>(); LRUCache lru = new LRUCache(k); for (int[] p : operators) { int op = p[0]; if (op == 1) { lru.put(p[1], p[2]); } else if (op == 2) { list.add(lru.get(p[1])); } } int n = list.size(); int[] ans= new int[n]; for (int i = 0; i < n; i++) ans[i] = list.get(i); return ans; } } class LRUCache { //定义双向链表节点 class Node { int k, v; Node l, r; Node(int _k, int _v) { k = _k; v = _v; } } int n; //储存缓存容量值 Node head, tail; //设置虚拟的头尾节点 Map map; //储存节点的key以及节点 public LRUCache(int capacity) { n = capacity; map = new HashMap<>(); head = new Node(-1, -1); tail = new Node(-1, -1); head.r = tail; tail.l = head; } int get(int key) { Node node = null; //在找到对应节点则将其挪到链表头部 if (map.containsKey(key)) { node = map.get(key); refresh(node); return node.v; } return -1; } void put(int key, int val) { Node node = null; //如果节点在map中,说明它也在链表中。因此更新其值,并将其挪到双向链表头部 if (map.containsKey(key)) { node = map.get(key); node.v = val; refresh(node); //将node挪到双向链表头部 return; } //如节点不在map中,则需要新建节点储存当前的key&val if (map.size() == n) { //储存空间不足,执行LRU算法。(在链表以及map中同时)删除双向链表尾部节点(最久未被访问节点) Node last = tail.l; map.remove(last.k); delete(last); } //将新节点放在链表头部 node = new Node(key, val); map.put(key, node); refresh(node); } //将当前访问的node挪到双向链表头部 void refresh(Node node) { delete(node); node.r = head.r; node.l = head; head.r.l = node; head.r = node; } //删除目标节点 void delete(Node node) { //若目标节点的左指针为空,则说明它不在双向链表中 if (node.l != null) { Node left = node.l; Node right = node.r; left.r = right; right.l = left; } } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)