460. LFU缓存

题目地址:https://leetcode-cn.com/problems/lfu-cache/submissions/

代码地址:https://github.com/javartisan/edx-ds/blob/master/src/main/java/com/javartisan/leetcode/LFUCache460.java

class LFUCache {

    private static class Node{
        public int key=-1;
        public int value=-1;
        public Node next;
        public Node lNext;
        public Node lBefore;
        public int count=1;
    }

    private int capacity;
    private int size;
    private int tabSize=15;

    private Node hashTab[];

    private Node head;
    private Node tail;

    public LFUCache(int capacity) {

        this.capacity =capacity;
        // 参见HashMap实现,必须+1,不然7的话,如果key=7则会数组越界
        hashTab =new Node[tabSize+1];
        head =new Node();
        tail = new Node();
        head.lNext=tail;
        tail.lBefore=head;
    }

    public int get(int key) {

        int hash =hash(key);
        Node node =hashTab[hash];
        while(node!=null){
            if(node.key==key){
                node.count=node.count+1;
                Node nodeNext =node.lNext;
                connect(node.lBefore,node.lNext);
                update(node,nodeNext);
                return node.value;
            }
            node=node.next;
        }
        return -1;

    }

    public void put(int key, int value) {
        if(capacity==0){
            return;
        }
        ensureCapacity(key);

        int hash = hash(key);
        Node node = hashTab[hash];
        if(node!=null){
            if(node.key==key){
                   node.value =value;
                   node.count=node.count+1;
                   connect(node.lBefore,node.lNext);
                   update(node,tail);

            }else{
                Node last=node;
                node =node.next;
                while(node!=null){
                    if(node.key==key){
                        node.value=value;
                        node.count=node.count+1;
                        connect(node.lBefore,node.lNext);
                           update(node,tail);
                        break;
                    }
                    last = node;
                    node=node.next;
                }
                if(node==null){
                    node = new Node();
                    node.key=key;
                    node.value=value;
                    last.next =node;
                    size++;
                    update(node,tail);
                }
            }
        }else{
            node = new Node();
            node.key=key;
            node.value=value;
            size++;
            hashTab[hash]=node;
            update(node,tail);
        }
    }

    public void update(Node node,Node currentNode){

        Node before = currentNode.lBefore;
        while(before!=null&&before!=head){
            if(before.count>node.count){
                break;
            }
            before=before.lBefore;
        }
        insert(node,before,before.lNext);
    }

    public boolean containKey(int key){
        int hash=hash(key);
        Node node =hashTab[hash];
        while(node!=null){
            if(node.key==key){
                return true;
            }
            node =node.next;
        }

        return false;
    }

    public void ensureCapacity(int key){

        if(size<capacity||(size==capacity&&containKey(key))){
            return ;
        }
        size--;
        Node delNode=tail.lBefore;
        Node before=delNode.lBefore;
        connect(before,tail);
        int hash=hash(delNode.key);
        Node node = hashTab[hash];
        if(node.key==delNode.key){
            hashTab[hash]=node.next;
            return;
        }
        Node last=node;
        node =node.next;
        while(node!=null){
            if(node.key==delNode.key){
                last.next=node.next;
            }
            last=node;
            node=node.next;
        }
    }

    public int hash(int key){
        // 使用2的N次方-1计算效率高,使用&分布更均匀
        return Math.abs(key)&tabSize;
    }

    public void connect(Node before,Node after){
        before.lNext = after;
        after.lBefore = before;
    }

    public void insert(Node insert,Node before,Node after){
            insert.lNext=after;
            insert.lBefore=before;
            before.lNext=insert;
            after.lBefore=insert;
    }

    public static void main(String[] args){
        LFUCache cache = new LFUCache(2);
        cache.put(1,1);
        cache.put(2,2);
        cache.put(3,3);
        System.out.println(cache.get(1));
        System.out.println(cache.get(2));
        System.out.println(cache.get(3));

    }

}

/**
 * Your LFUCache object will be instantiated and called as such:
 * LFUCache obj = new LFUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

原文地址:https://www.cnblogs.com/leodaxin/p/11329927.html

时间: 2024-10-15 01:35:58

460. LFU缓存的相关文章

leetcode 460 LFU缓存

原题点这里 class Node implements Comparable<Node>{ public int key; public int value; public int lastTime; public int fre; public Node(int key,int value,int lastTime){ this.key=key; this.value=value; this.lastTime = lastTime; this.fre=1; } @Override publi

460. LFU Cache

460. LFU Cache Total Accepted: 5305 Total Submissions: 26292 Difficulty: Hard Contributors: 1337c0d3r, fishercoder Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the following operations: getand put. ge

-实现 LFU 缓存算法

-实现 LFU 缓存算法, 设计一个类 LFUCache,实现下面三个函数 + 构造函数: 传入 Cache 内最多能存储的 key 的数量 + get(key):如果 Cache 中存在该 key,则返回对应的 value 值,否则,返回-1. + set(key,value):如果 Cache 中存在该 key,则重置 value 值:如果不存在该 key,则将该 key 插入到到 Cache 中,若插入后会导致 Cache 中存储的 key 个数超过最大容量,则在插入前淘汰访问次数最少的数

[LeetCode] 460. LFU Cache 最近最不常用页面置换缓存器

Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the following operations: get and put. get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.pu

LFU缓存

https://leetcode-cn.com/problems/lfu-cache/description/ 缓存的实现可以采取多种策略,不同策略优点的评估就是"命中率".好的策略可以实现较高的命中率.常用的策略如:LRU(最近最少使用).LFU(最不频繁使用).这两种策略都可以在O(1)时间内实现get和put.本文主要讲讲LFU的实现. import java.util.HashMap; import java.util.LinkedHashSet; class LFUCache

【Leetcode刷题】LFU缓存

题目:https://leetcode-cn.com/problems/lfu-cache/ 思路: O(1)的数据结构:hashmap 维持最近使用:OrderdDict(详见LRU缓存问题) 使用一个hashmap维系key到出现频率的映射关系 另一个hashmap维系频率到数据(key-value键值对)的关系 由于 当存在平局(即两个或更多个键具有相同使用频率)时,应该去除 最近 最少使用的键.因此key-value键值对应该用OrderdDict存储 import collection

LeetCode &quot;460. LFU Cache&quot; !

My first try was very close to a final solution .. however, this is a much neater solution: https://discuss.leetcode.com/topic/69436/concise-c-o-1-solution-using-3-hash-maps-with-explanation Lesson learnt: data structure is crucial. And, if some logi

leet

# 题名1 两数之和    2 两数相加    3 无重复字符的最长子串    4 寻找两个有序数组的中位数    5 最长回文子串    6 Z 字形变换    7 整数反转    8 字符串转换整数 (atoi)    9 回文数    10 正则表达式匹配    11 盛最多水的容器    12 整数转罗马数字    13 罗马数字转整数    14 最长公共前缀    15 三数之和    16 最接近的三数之和    17 电话号码的字母组合    18 四数之和    19 删除链表

详解三种缓存过期策略LFU,FIFO,LRU(附带实现代码)

在学操作系统的时候,就会接触到缓存调度算法,缓存页面调度算法:先分配一定的页面空间,使用页面的时候首先去查询空间是否有该页面的缓存,如果有的话直接拿出来,如果没有的话先查询,如果页面空间没有满的时候,使用新页面的时候,就释放旧的页面空间,把新页面缓存起来,以便下次使用同样的页面的时候方便调用. 缓存调度流程图 缓存机制就是上面所说的那样,但是实现的过程以及淘汰旧页面的机制不同,所以会有不同缓存调度方法,就常见的就是FIFO,LRU,LFU缓存过期策略. 1.FIFO(First In First