LRU算法&&LeetCode解题报告
题目
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
思路
原理是:
- 双向链表根据每一个节点近期被訪问的时间有序存储,近期被訪问的节点存储在表头,近期没有被訪问的节点存储的表尾,存储根据是由于:近期被訪问的节点在接下来的一段时间仍有非常大的概率被再次訪问到。
- 哈希表的作用是用来提高查找效率,假设不使用哈希表。则查找一个节点的时间复杂度是O(n)。而使用了哈希表,则每一个节点的查找时间复杂度为O(1)。
- 依据键值查找hashmap,假设没找到直接返回-1
- 若找到相应节点node,则将其插入到双向链表表头
- 返回node的value值
- 依据键值查找hashmap。假设找到。则直接将该节点移到表头就可以
- 假设没有找到。首先推断当前Cache是否已满
- 假设已满,则删除表尾节点
- 将新节点插入到表头
AC代码
import java.util.HashMap; public class LRUCache {
private HashMap<Integer, DoubleListNode> mHashMap;
private DoubleListNode head;
private DoubleListNode tail;
private int capacity;
private int currentsize; public LRUCache(int capacity) {
this.capacity = capacity;
this.currentsize = 0;
this.mHashMap = new HashMap<Integer, DoubleListNode>();
this.head = this.tail = null;
} public int get(int key) {
if (mHashMap.containsKey(key)) {
DoubleListNode tNode = mHashMap.get(key);
if (tNode == tail) {
if (currentsize > 1) {
removeNodeFromTail();
moveNodeToHead(tNode);
}
} else if (tNode == head) {
// do nothing
} else {
tNode.pre.next = tNode.next;
tNode.next.pre = tNode.pre;
moveNodeToHead(tNode);
}
return mHashMap.get(key).value;
} else {
return -1;
}
} private void removeNodeFromTail() {
tail = tail.pre;
if (tail != null) {
tail.next = null;
}
} private void moveNodeToHead(DoubleListNode node) {
head.pre = node;
node.next = head;
node.pre = null;
head = node;
} public void set(int key, int value) {
if (mHashMap.containsKey(key)) {
// 更新HashMap中相应的值,并将key相应的Node移至队头
DoubleListNode tNode = mHashMap.get(key);
tNode.value = value;
if (tNode == tail) {
if (currentsize > 1) {
removeNodeFromTail();
moveNodeToHead(tNode);
}
} else if (tNode == head) {
// do nothing
} else {
tNode.pre.next = tNode.next;
tNode.next.pre = tNode.pre;
moveNodeToHead(tNode);
} mHashMap.put(key, tNode);
} else {
DoubleListNode node = new DoubleListNode(key, value);
mHashMap.put(key, node);
if (currentsize == 0) {
head = tail = node;
currentsize += 1;
} else if (currentsize < capacity) {
moveNodeToHead(node);
currentsize += 1;
} else {
// 删除tail节点。而且添加一个head节点
mHashMap.remove(tail.key);
removeNodeFromTail(); // 添加头节点
moveNodeToHead(node);
}
}
} public static void main(String[] args) {
LRUCache lruCache = new LRUCache(1);
lruCache.set(2, 1);
System.out.println(lruCache.get(2));
lruCache.set(3, 2);
System.out.println(lruCache.get(2));
System.out.println(lruCache.get(3));
} private static class DoubleListNode {
public DoubleListNode pre;
public DoubleListNode next;
public int key;
public int value; public DoubleListNode(int key, int value) {
this.key = key;
this.value = value;
this.pre = this.next = null;
}
} }
LRU算法&&LeetCode解题报告的更多相关文章
- leetcode解题报告(2):Remove Duplicates from Sorted ArrayII
描述 Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? For ex ...
- 2021字节跳动校招秋招算法面试真题解题报告--leetcode206 反转链表,内含7种语言答案
206.反转链表 1.题目描述 反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1-> ...
- LeetCode解题报告:Linked List Cycle && Linked List Cycle II
LeetCode解题报告:Linked List Cycle && Linked List Cycle II 1题目 Linked List Cycle Given a linked ...
- 2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案
2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案 1.题目描述 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. ...
- LeetCode 解题报告索引
最近在准备找工作的算法题,刷刷LeetCode,以下是我的解题报告索引,每一题几乎都有详细的说明,供各位码农参考.根据我自己做的进度持续更新中...... ...
- LeetCode解题报告:LRU Cache
LRU Cache Design and implement a data structure for Least Recently Used (LRU) cache. It should suppo ...
- LeetCode解题报告—— Search in Rotated Sorted Array & Search for a Range & Valid Sudoku
1. Search in Rotated Sorted Array Suppose an array sorted in ascending order is rotated(轮流,循环) at so ...
- LeetCode解题报告—— 1-bit and 2-bit Characters & 132 Pattern & 3Sum
1. 1-bit and 2-bit Characters We have two special characters. The first character can be represented ...
- leetCode解题报告5道题(六)
题目一: Longest Substring Without Repeating Characters Given a string, find the length of the longest s ...
随机推荐
- Spring 3整合Quartz 2实现定时任务一:常规整合 (基于maven构建)
最近工作中需要用到定时任务的功能,虽然Spring3也自带了一个轻量级的定时任务实现,但感觉不够灵活,功能也不够强大.在考虑之后,决定整合更为专业的Quartz来实现定时任务功能. 首先,当然是添加依 ...
- C#学习笔记二:C#程序结构
从最简单的HelloWorld开始入手,这是一个最低限度的C#程序结构. C# Hello World 示例 一个C#程序主要由以下几部分组成: 命名空间声明 一个类 类方法 类属性 一个Main方法 ...
- POJ 2075 Tangled in Cables 最小生成树
简单的最小生成树,不过中间却弄了很久,究其原因,主要是第一次做生成树,很多细节不够熟练,find()函数的循环for判断条件是 pre[i]>=0,也就是遇到pre[i]==-1时停止,i就是并 ...
- *string++优先级的问题
这个东西困扰了我几天,关于优先级问题确实是个恼人的东西,为了这个专门翻了C语言课本,得知 所有一目运算符都是第二级优先级 结合性是从右到左 那么*string++应该就是*(string++),也就是 ...
- Android中的Parcel机制 实现Bundle传递对象
Android中的Parcel机制 实现了Bundle传递对象 使用Bundle传递对象,首先要将其序列化,但是,在Android中要使用这种传递对象的方式需要用到Android Parc ...
- 没有document.getElementByName
首先声明的是: document.getElementByName方法没有.document.getElementsByName得到的是标签的数组 document.getElementId得到的是某 ...
- Java 多维数组 按某列 排序
public MetaCell[][] getByColumn(final int columnIndex, int decisionIndex) {//[注意]final咯 ...
- nginx+gunicorn
wsgi接口,使用gunicorn作为server,想在外层加nginx. 配置了 proxy_pass http://127.0.0.1:9008; 访问报301. 参考gunicorn 官网配 ...
- [C# 网络编程系列]专题七:UDP编程补充——UDP广播程序的实现
转自:http://www.cnblogs.com/zhili/archive/2012/09/03/2666974.html 上次因为时间的关系,所以把上一个专题遗留下的一个问题在本专题中和大家分享 ...
- Kia's Calculation(HDU 4267)
Problem Description Doctor Ghee is teaching Kia how to calculate the sum of two integers. But Kia is ...