Java for LeetCode 146 LRU Cache 【HARD】
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.
解题思路:
实现LRU算法的缓冲类,由于cache会有频繁的读改操作,所以要有合适的数据结构来让 set 和 get 的复杂度很小,最好近 O(1)。
主要有两种思路:
一、用 Splay 实现,Splay 是棵 BST,同时在查找和修改的时候会让那个节点上浮到根节点,不过操作都是 O(log(n)) 级别的,而且有个问题,就是这棵树可能会变成一条链(正常节点都是按查询频率从上到下,所以很快,均摊小于 O(log(n)))。Splay 实现过于复杂,这里就不给出。
二、用双链表和 HashMap 实现。
链表的作用是记录节点的使用顺序。正常情况下 LRU 都是用这种做法的。
HashMap 实现用 key 找到 List 中的节点对象,找不到就在 List 中增加节点,并插入 HashMap。
按照要求得到或修改节点的 value。
修改节点的使用时间,也就是把 List 中的节点拉到 List 头部。
在第一步时如果节点个数大于可用容量,就将 List 的最后一个节点删去。
JAVA实现如下:
- package oj.leetcode;
- import java.util.*;
- public class LRUCache {
- private int capacity;
- private Node head, tail;
- private HashMap<Integer, Node> keyNodeMap;
- public LRUCache(int capacity) {
- this.capacity = capacity;
- head = new Node(-1, -1);
- tail = new Node(0, 0);
- head.next = tail;
- tail.pre = head;
- this.keyNodeMap = new HashMap<Integer, Node>();
- }
- public int get(int key) {
- Node node = keyNodeMap.get(key);
- if (node != null) {
- moveToHead(node);
- return node.value;
- }
- return -1;
- }
- public void set(int key, int value) {
- Node node = null;
- if (keyNodeMap.containsKey(key)) {
- node = keyNodeMap.get(key);
- node.value = value;
- } else {
- node = new Node(key, value);
- if (keyNodeMap.size() == capacity) {
- keyNodeMap.remove(removeTail());
- }
- keyNodeMap.put(key, node);
- }
- moveToHead(node);
- }
- private void moveToHead(Node node) {
- if (node.pre != null || node.next != null) {
- node.next.pre = node.pre;
- node.pre.next = node.next;
- }
- node.next = head.next;
- head.next.pre = node;
- node.pre = head;
- head.next = node;
- }
- private int removeTail() {
- int lastKey = -1;
- if (tail.pre != head) {
- Node lastNode = tail.pre;
- lastKey = lastNode.key;
- lastNode.pre.next = tail;
- tail.pre = lastNode.pre;
- lastNode = null;
- }
- return lastKey;
- }
- class Node{
- int key;
- int value;
- Node pre;
- Node next;
- public Node(int k, int v) {
- key = k;
- value = v;
- }
- }
- }
Java for LeetCode 146 LRU Cache 【HARD】的更多相关文章
- leetcode 146. LRU Cache 、460. LFU Cache
LRU算法是首先淘汰最长时间未被使用的页面,而LFU是先淘汰一定时间内被访问次数最少的页面,如果存在使用频度相同的多个项目,则移除最近最少使用(Least Recently Used)的项目. LFU ...
- leetcode 146. LRU Cache ----- java
esign and implement a data structure for Least Recently Used (LRU) cache. It should support the foll ...
- [LeetCode] 146. LRU Cache 最近最少使用页面置换缓存器
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
- [LeetCode] 146. LRU Cache 近期最少使用缓存
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
- Java实现 LeetCode 146 LRU缓存机制
146. LRU缓存机制 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - ...
- leetcode@ [146] LRU Cache (TreeMap)
https://leetcode.com/problems/lru-cache/ Design and implement a data structure for Least Recently Us ...
- Leetcode#146 LRU Cache
原题地址 以前Leetcode的测试数据比较弱,单纯用链表做也能过,现在就不行了,大数据会超时.通常大家都是用map+双向链表做的. 我曾经尝试用C++的list容器来写,后来发现map没法保存lis ...
- Java for LeetCode 207 Course Schedule【Medium】
There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prer ...
- Java for LeetCode 072 Edit Distance【HARD】
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...
随机推荐
- CSS布局自适应高度解决方法
这是一个比较典型的三行二列布局,每列高度(事先并不能确定哪列的高度)的相同,是每个设计师追求的目标,按一般的做法,大多采用背景图填充.加JS脚本的方法使列的高度相同,本文要介绍的是采用容器溢出部分隐藏 ...
- fedora安装软件
jdk 1.下载rpm包 注意32位还是64位,注意是rpm格式 2.安装 sudo rpm -ivh jdk.rpm sudo update-alternatives --config java # ...
- 洛谷P1136 迎接仪式
题目描述 LHX教主要来X市指导OI学习工作了.为了迎接教主,在一条道路旁,一群Orz教主er穿着文化衫站在道路两旁迎接教主,每件文化衫上都印着大字.一旁的Orzer依次摆出“欢迎欢迎欢迎欢迎……”的 ...
- bzoj2054 疯狂的馒头
bzoj上现在找不到这题,所以目前只是过了样例,没有测 2054: 疯狂的馒头 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 715 Solved: ...
- jsp学习(五)
在进行jsp与jdbc连接时,出现这样一个错误,提示如下: java.net.ConnectException: Connection refused: connect 后来发现是由于mysql数据库 ...
- sql server规范
常见的字段类型选择 1.字符类型建议采用varchar/nvarchar数据类型 2.金额货币建议采用money数据类型 3.科学计数建议采用numeric数据类型 4.自增长标识建议采用bigint ...
- 嵌入式实时操作系统μCOS原理与实践任务控制与时间的解析
/*************************************************************************************************** ...
- 得分(Score,ACM/ICPC Seoul 2005,UVa 1585)
#include<stdio.h> int main(void) { char b; int t,cou,sum; scanf("%d",&t); getcha ...
- 网友微笑分享原创Jquery实现瀑布流特效
首先非常感谢网友微笑的无私分享,此Jquery特效是一款非常流行和实用的瀑布流布局,核心代码只有几十行,是我见过代码量最少的瀑布流布局,非常适合网友们学习哦,希望大家好好看一下这个Jquery特效的原 ...
- JS动态调用方法名示例介绍
先看看JS的一个函数 JavaScript eval() 函数 定义和用法 eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码. 语法 eval(string) 参数 描 ...