看到这个问题,可能拿到手就想用LinkedHashMap来几分钟就给实现了,确实也可以,但是现在很多面试要求你不用LinkedHashMap能不能实现这个问题,基于面试的这种要求,我开了这篇博客:


(常规解法)基于 LinkedHashMap 实现:

class LRUCache {Map<Integer,Integer> map;private int capacity;private int size = 0;public LRUCache(int capacity) {map = new LinkedHashMap<>(); this.capacity = capacity;}public int get(int key) {if(map.containsKey(key)){int v = map.get(key);map.remove(key);map.put(key,v);return v;}return -1;}public void put(int key, int value) {if(capacity == 0) return;if(map.containsKey(key)){map.remove(key);map.put(key, value);return;}if(size >= capacity){size --;map.remove(map.entrySet().iterator().next().getKey());}map.put(key, value);size++;}
}

面试要求解法:使用双链表+HashMap

import java.util.HashMap;
import java.util.Map;public class LRUCache {class DoubleNode{int val;int key;DoubleNode next;DoubleNode pre;public DoubleNode(int key, int val){this.val = val;this.key = key;}public DoubleNode(){}}DoubleNode fakehead = new DoubleNode();DoubleNode faketail = new DoubleNode();private int size;private int capacity;private Map<Integer, DoubleNode> map;public LRUCache(int capacity){map = new HashMap<>();fakehead.next = faketail;faketail.pre = fakehead;this.capacity = capacity;this.size = 0;}public int get(int key){if(!map.containsKey(key)){return -1;}moveToHead(map.get(key));return map.get(key).val;}private void moveToHead(DoubleNode node) {  // 将链表节点移动到头部 = 删除当前节点+把当前节点重新放到头部delete(node);addToHead(node);}public void delete(DoubleNode node){node.pre.next = node.next;node.next.pre = node.pre; // 删除完毕}public void put(int key, int value){ DoubleNode node = map.get(key);if(node == null){ // 新建一个节点放在头部DoubleNode newNode = new DoubleNode(key, value); map.put(key, newNode);addToHead(newNode);size++;if(size > capacity){DoubleNode temp = faketail.pre;delete(temp);map.remove(temp.key);size--;}}else{node.val = value;moveToHead(node);}}private void addToHead(DoubleNode node) { // 把node放在头部node.next = fakehead.next;fakehead.next = node;node.pre = node.next.pre;node.next.pre = node;}
}

如果不想自己实现双链表,可以用自带的链表实现:

class LRUCache {private int size;private int capacity;private Map<Integer,Integer> cache;private LinkedList<Integer> doubleNode;public LRUCache(int capacity) {this.capacity = capacity;cache = new HashMap<>();doubleNode = new LinkedList<>();}public int get(int key) {if(!cache.containsKey(key)) return -1;else{int value = cache.get(key);doubleNode.remove(Integer.valueOf(key));doubleNode.addFirst(key);return value;}}public void put(int key, int value) {if(capacity == 0) return;if(cache.containsKey(key)){cache.put(key, value);doubleNode.remove(Integer.valueOf(key));doubleNode.addFirst(key);}else{size++;if(size > capacity){size--;Integer ano_key = doubleNode.getLast();cache.remove(ano_key);doubleNode.remove(ano_key);}cache.put(key, value);doubleNode.addFirst(key);}}
}/*** Your LRUCache object will be instantiated and called as such:* LRUCache obj = new LRUCache(capacity);* int param_1 = obj.get(key);* obj.put(key,value);*/

经过检验,用自带的LinkedHashMap,效率最高。

通常情况下,面试要求大家15分钟之内实现双链表的这种解法。

LRU的两种实现方案相关推荐

  1. android 热更新 方案,热更新-热更新app开发的两种系统方案!

    针对app开发工作人员来讲,除开要会编码,热更新也是一定要学好和把握的方法,从技术性视角而言,热更新对Android和iOS各自有不一样的系统软件方案,为了更好地让大伙儿掌握这二种系统方案的差别,今日 ...

  2. 模板方法设计模式两种实现方案

    目录 1.模板方法设计模式 2.继承实现方案 3.依赖实现方案 3.1 spring-jdbc 中的 JdbcTemplate 3.2  阿里分布式事务框架Seata中的ExecuteTemplate ...

  3. 处理接口幂等性的两种常见方案

    在上周发布的 TienChin 项目视频中,我和大家一共梳理了六种幂等性解决方案,接口幂等性处理算是一个非常常见的需求了,我们在很多项目中其实都会遇到.今天我们来看看两种比较简单的实现思路. 1. 接 ...

  4. 两种复试方案!这所大学发布考研复试相关通知!

    前段时间,小编推送过一些文章,描述了部分大学可能采用网络复试的问题: 真的要[网络复试]?三所211大学发通知! 但是后来,由于疫情发展变化较快,也不清楚到底用什么复试方式,因此这些消息也没有后续了. ...

  5. Apache之——多虚拟主机多站点配置的两种实现方案

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/48213523 Apache中配置多主机多站点,可以通过两种方式实现: 将同一个域名 ...

  6. (三)Redis两种持久化方案

    Redis的持久化策略:2种 RDB方式的持久化是通过快照(snapshotting)完成的,当符合一定条件时Redis会自动将内存中的数据进行快照并持久化到硬盘.RDB是Redis默认采用的持久化方 ...

  7. EHIGH恒高:大话UWB技术之TDOA与TOF两种技术方案对比

    超宽带(UWB技术)是一种基于IEEE802.15.4a和802.15.4z标准的无线电技术,它能够非常准确地测量无线电信号的飞行时间,从而实现厘米精度的距离/位置测量.不同于蓝牙.WiFi等其他定位 ...

  8. iphoneX 前端两种适配方案

    方案一: 为适应于iphoneX的齐刘海,ios11的WebView Viewport对于顶部做了调整. iphoneX Viewport 手机浏览器是把页面放在一个虚拟的"窗口" ...

  9. 日均数据量千万级,MySQL、TiDB 两种存储方案的落地对比

    盖娅广告匹配系统(GaeaAD)用于支撑盖娅互娱全平台实时广告投放系统,需要将广告数据和游戏 SDK 上报的信息进行近实时匹配,本质上来说需要实时的根据各个渠道的广告投放与相应渠道带来的游戏玩家数据进 ...

最新文章

  1. java $.getjson_JQuery 获取json数据$.getJSON方法的实例代码
  2. TypeError: new(): data must be a sequence (got float)
  3. 回归素材(part7)--机器学习入门到实战-MATLAB实践应用
  4. 用chkconfig配置linux自启动服务
  5. 卡通角色表情驱动系列一
  6. 每天30分钟:成功有效的学习方法
  7. 数据结构实验之栈六:下一较大值(二)
  8. Cacti设置流量阀值实现邮件报警
  9. Mybatis系列全解(六):Mybatis最硬核的API你知道几个?
  10. 惨遭数百万开发者厌弃的五大编程语言!
  11. QT设计师(designer)下载安装
  12. 一分钟实现扫描二维码功能
  13. Python迭代器基本方法iter()及其魔法方法__iter__()原理详解
  14. R语言导入数据文件(数据导入、加载、读取)、使用readr包中的read_csv函数导入逗号分割文件CSV(Comma Delimited Text File)
  15. 卡耐基梅隆大学赢得DARPA网络挑战赛
  16. Vue3动态引入Element-plus icon图标
  17. 简述弹性盒子flex布局及rem布局
  18. 数据结构实验8:内部排序
  19. 【TypeScript】Object、object和{}类型
  20. linux 查看公网ip

热门文章

  1. 【Android Demo】简单手机通讯录
  2. DBA必知的mysql备份与还原的几大方法
  3. 九章算术卷第一 方田
  4. 免费mac虚拟机下载 快速安装win系统
  5. ASP.NET中Url重写后,打不开真正的Html页面
  6. 今天提交了一个patch开心,呵呵
  7. Linux(CentOS 5.4 Linux)服务器配置之DHCP服务器配置应用
  8. centOS 7下安装与配置heartbeat高可用集群
  9. 【BZOJ4774】修路 [斯坦纳树]
  10. 真正解决ASP.NET每一个页面首次访问超级慢的问题