题解 | #设计LFU缓存结构#

设计LFU缓存结构

http://www.nowcoder.com/practice/93aacb4a887b46d897b00823f30bfea1


import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

class LFU {
    static class Node {
        int freq;
        int key;
        int value;
        public Node (int freq, int key, int value) {
            this.freq = freq;
            this.key = key;
            this.value = value;
        }
    }

    // 对应节点key值->对应节点的map
    Map<Integer, Node> mp = new HashMap<>();
    // 对应节点频率值->对应节点的双向链表的map
    Map<Integer, LinkedList<Node>> freq_mp = new HashMap<>();

    int size = 0;
    int min_freq = 1;
    int capacity = 0;

    public LFU (int capacity) {
        this.capacity = capacity;
    }

    public void set(int key, int value) {
        // 先看有没有
        Node node = mp.get(key);
        if (node == null) {
            // 不存在这个节点
            // 看当前容量是否足够
            if (size < capacity) {
                // 足够,放进来
                LinkedList<Node> list = freq_mp.get(1);
                Node newNode = new Node(1, key, value);
                min_freq = 1;
                mp.put(key, newNode);
                if (list == null) {
                    freq_mp.put(1, new LinkedList<>());
                    list = freq_mp.get(1);
                }
                list.offer(newNode);
                size++;

            } else {
                // 不够,则将最近最少使用的移出去,然后再把新的放进来
                LinkedList<Node> list = freq_mp.get(min_freq);
                Node old = list.poll();
                if (old == null) {
                    // 这里,old可能为null,为什么?
                    // 因为min_freq有可
                    // 错误
                    System.out.println("min_freq = " + min_freq);
                    System.out.println("error");
                    return;
                }
                mp.remove(old.key);
                Node newNode = new Node(1, key, value);
                min_freq = 1;
                mp.put(key, newNode);
                list = freq_mp.get(1);
                if (list == null) {
                    freq_mp.put(1, new LinkedList<>());
                    list = freq_mp.get(1);
                }
                list.offer(newNode);
            }
        } else {
            // 已经存在这个节点了,则直接set并使其freq+1
            int freq = node.freq;
            freq_mp.get(freq).remove(node);
            if (freq_mp.get(freq).isEmpty()) min_freq += 1;
            node.freq += 1;
            node.value = value;
            LinkedList<Node> list = freq_mp.getOrDefault(freq + 1, new LinkedList<>());
            list.offer(node);
            freq_mp.put(freq + 1, list);
        }
    }

    public int get(int key) {
        Node node = mp.get(key);
        if (node == null) {
            // 无这个节点
            return -1;
        } else {
            // 有这个节点,则其使用freq+1
            int freq = node.freq;
            freq_mp.get(freq).remove(node);
            if (freq_mp.get(freq).isEmpty()) min_freq += 1;
            node.freq += 1;
            LinkedList<Node> list = freq_mp.getOrDefault(freq + 1, new LinkedList<>());
            list.offer(node);
            freq_mp.put(freq + 1, list);
        }
        return node.value;
    }
}

public class Solution {

    public int[] LFU (int[][] operators, int k) {
        LFU lfu = new LFU(k);
        ArrayList<Integer> ans = new ArrayList<>();
        if (operators == null || operators.length == 0) {
            return new int[0];
        }
        for (int[] operator : operators) {
            int key = operator[1];
            switch (operator[0]) {
                case 1:
                    int value = operator[2];
                    lfu.set(key, value);
                    break;
                case 2:
                    ans.add(lfu.get(key));
                    break;
            }
        }
        int[] ansArray = new int[ans.size()];
        for (int i = 0; i < ans.size(); i++) {
            ansArray[i] = ans.get(i);
        }
        return ansArray;
    }

    public static void main (String[] args) {
        Solution solution = new Solution();
        int[][] operators = {{1,1,1},{1,2,2},{1,3,2},{1,2,4},{1,3,5},{2,2},{1,4,4},{2,1}};
        int[] ans = solution.LFU(operators, 3);
        for (int i = 0; i < ans.length; i++) {
            System.out.println(ans[i] + " ");
        }
    }
}

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务