IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> leetcode面试题 16.25. LRU 缓存 LinkedHashMap + 哈希表与单链表 + 哈希表与双链表 -> 正文阅读

[数据结构与算法]leetcode面试题 16.25. LRU 缓存 LinkedHashMap + 哈希表与单链表 + 哈希表与双链表

解题思路
最先想到的是哈希表加单链表的方式:由于get和put都视为是一次使用,所以在get和put之后都要将节点移动到链表的最前面(最前面的表示最近一次使用的,显然最后面的一个就是要被淘汰的一个)
哈希表中记录的是key-value值,链表上只存放key值即可,不断地调整链表上的key的排列顺序即可实现最近最久未使用的排序效果。
这种做法问题挺多的,一个是map中没有存放key对应的链表节点,导致在寻找链表上的节点时需要顺序遍历链表,这导致我写的程序 花费300多ms...

改进的办法就是map中存放对应的链表节点,这样在调整顺序的时候可以直接从map中找到对应的节点,大大缩短时间。

另外,在删除的时候,我们需要删除链表最后一个节点,那么由这个需求,很容易想到循环单链表或者有头尾节点的双链表,这两种做法应该都是可以的,只不过 双链表可能操作起来更清晰 更舒服一些

最后,有一个完美的数据结构就可以解决这个问题,LinkedMapHashMap 它的特点是会按顺序将我们插入的节点链接起来,底层是用单链表实现的。
这样就方便了,get的时候 如果之前有这个key,那么就删除之前的数据,然后重新put到链表的末尾,显然链表的第一个元素就是我们需要删除的(如果需要的话),
put的时候先put,然后检查容量是否符合要求,决定是否删除第一个map元素。

代码
解法一:LinkedHashMap

?class LRUCache
{
? ? LinkedHashMap<Integer,Integer> map = null;
? ? int capacity;
? ? public LRUCache(int capacity) {
? ? ? map = new LinkedHashMap<>();
? ? ? ? this.capacity = capacity;
? ? }

? ? public int get(int key)
? ? {
? ? ? ? if(map.containsKey(key)){
? ? ? ? ? ? Integer value = map.get(key);
? ? ? ? ? ? map.remove(key);
? ? ? ? ? ? map.put(key,value);
? ? ? ? ? ? return ?value;

? ? ? ? }else{
? ? ? ? ? ? return -1;
? ? ? ? }

? ? }


? ? public void put(int key, int value) {
? ? ? ? if(map.containsKey(key)){
? ? ? ? ? ? map.remove(key);
? ? ? ? ? ? map.put(key,value);
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? map.put(key,value);
? ? ? ? ? if(map.size() > capacity){
? ? ? ? ? ? ? map.remove(map.keySet().iterator().next());
? ? ? ? ? }
? ? }

}
解法二:哈希表加单链表


class Node{
? ? Node next;
? ? int val;

? ? public Node() {
? ? }

? ? @Override
? ? public String toString() {
? ? ? ? return "Node{" +
? ? ? ? ? ? ? ? "next=" + next +
? ? ? ? ? ? ? ? ", val=" + val +
? ? ? ? ? ? ? ? '}';
? ? }

? ? public Node getNext() {
? ? ? ? return next;
? ? }

? ? public void setNext(Node next) {
? ? ? ? this.next = next;
? ? }

? ? public int getVal() {
? ? ? ? return val;
? ? }

? ? public void setVal(int val) {
? ? ? ? this.val = val;
? ? }

? ? public Node( int val) {
? ? ? ? this.val = val;
? ? }

}
class LRUCache {
? ? HashMap<Integer,Integer> map = null;
? ? int capactity;
? ? Node head = null;
? ? public LRUCache(int capacity) {
? ? ? ? head = ?new Node();
? ? ? ? head.next = null;
? ? ? ? this.capactity ?= capacity;
? ? ? ? map = new HashMap<>();
? ? }

? ? public int get(int key) {
? ? ? ? int res = ?map.getOrDefault(key,-1) ;
? ? ? ? if (res == -1){
? ? ? ? ? ? return -1;
? ? ? ? }else{
? ? ? ? ? ? //执行排序操作 移动到最前面
? ? ? ? ? ? Node p = head;
? ? ? ? ? ? Node q = p;
? ? ? ? ? ? p = p.next;
? ? ? ? ? ? while(p!=null){
? ? ? ? ? ? ? ? if(p.val == key){
? ? ? ? ? ? ? ? ? ? q.next = p.next;
? ? ? ? ? ? ? ? ? ? p.next = head.next;
? ? ? ? ? ? ? ? ? ? head.next = p;
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? ? ?q = p;
? ? ? ? ? ? ? ? ? ?p = p.next;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? return res;
? ? ? ? }
? ? }

? ? public void put(int key, int value) {//put 也会使保持为最新的排序
? ? ? ? if(map.get(key) == null){
? ? ? ? ? ? if(map.size()<capactity){
? ? ? ? ? ? ? ? map.put(key,value);
? ? ? ? ? ? ? ? Node p,q=head;
? ? ? ? ? ? ? ? p = head.next;
? ? ? ? ? ? ? ? while(p!=null){
? ? ? ? ? ? ? ? ? ? q = p;
? ? ? ? ? ? ? ? ? ? p = p.next;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? q.next = new Node(key);
? ? ? ? ? ? ? ? get(key);
? ? ? ? }else{
? ? ? ? ? ? //执行删除
? ? ? ? ? ? ? ? map.put(key,value);
? ? ? ? ? ? ? ? Node p = head;
? ? ? ? ? ? ? ? Node q = p;
? ? ? ? ? ? ? ? p = head.next;
? ? ? ? ? ? ? ? while(p.next!=null){
? ? ? ? ? ? ? ? ? ? q = p;
? ? ? ? ? ? ? ? ? ? p = p.next;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? map.remove(p.val);
? ? ? ? ? ? ? ? p = null;
? ? ? ? ? ? ? ? q.next = null;

? ? ? ? ? ? ? ? //插入新的
? ? ? ? ? ? ? ? Node p1,q1=head;
? ? ? ? ? ? ? ? p1 = head.next;
? ? ? ? ? ? ? ? while(p1!=null){
? ? ? ? ? ? ? ? ? ? q1 = p1;
? ? ? ? ? ? ? ? ? ? p1 = p1.next;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? q1.next = new Node(key);
? ? ? ? ? ? ? ? get(key);


? ? ? ? ? ? }
? ? ? ? }else{
? ? ? ? ? ? //重复的key为修改
? ? ? ? ? ? map.put(key,value);
? ? ? ? ? ? get(key);
? ? ? ? }
? ? }
}

解法三:哈希表加双链表

?class LRUCache4
{
? ? LinkedHashMap<Integer,Integer> map = null;
? ? int capacity;
? ? public LRUCache4(int capacity) {
? ? ? map = new LinkedHashMap<>();
? ? ? ? this.capacity = capacity;
? ? }

? ? public int get(int key)
? ? {
? ? ? ? if(map.containsValue(key)){
? ? ? ? ? ? Integer value = map.get(key);
? ? ? ? ? ? map.remove(key);
? ? ? ? ? ? map.put(key,value);
? ? ? ? ? ? return ?value;

? ? ? ? }else{
? ? ? ? ? ? return -1;
? ? ? ? }

? ? }


? ? public void put(int key, int value) {
? ? ? ? if(map.containsKey(key)){
? ? ? ? ? ? map.remove(key);
? ? ? ? ? ? map.put(key,value);
? ? ? ? ? ? return;
? ? ? ? }

作者:lingluan533
链接:https://leetcode-cn.com/problems/lru-cache-lcci/solution/linkedhashmap-ha-xi-biao-yu-dan-lian-bia-a9kb/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-24 18:44:08  更:2021-12-24 18:45:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 17:28:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码