春招冲刺Day4[高频算法题] --自己动手实现个LRU,要求带泛型

在这里插入图片描述
在这里插入图片描述

注意::

(1)LRU中head,tail是两个dummy节点,在构造方法中都指向了两个节点,这样的好处是统一进行添加和删除操作,而不用针对头,尾节点进行另外的删除操作!!
2. PUT操作时,如果是需要更新,那么先把需要更新的节点从双向链表中断开,再移动到头部;如果是新增的,需要考虑是否需要置换,置换时需要把hashMap中的key删除掉

import java.util.HashMap;
public class LRU<K,V> {

    private HashMap<K,Node<K,V>> map;
    private int size;
    private Node<K,V> head;
    private Node<K,V> tail;

    private static class Node<K,V>{
        Node<K,V> prev;
        Node<K,V> next;
        K key;
        V value;

        public Node(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }

    public LRU(int size) {
        head = new Node<>(null,null);
        tail = new Node<>(null,null);
        head.next = tail;
        tail.prev = head;
        map = new HashMap<>(size);
        this.size = size;
    }

    public V get(K key){
        Node<K, V> node = map.get(key);
        if(node == null) return null;
        //先移除该节点
        removeNode(node);
        //然后把该节点插到头节点后面
        insertAfterHead(node);
        return node.value;
    }

    public void put(K key, V val){
        Node<K, V> node = map.get(key);
        //需要更新值,并且需要移动到头部
        if(node != null){
            node.value = val;
            removeNode(node);
        }else{
            //LRU已满,需要置换末尾节点
            if(map.size() == size){
                //Node<K, V> removeNode = map.remove(tail.prev.key);
                //removeNode(removeNode);
                removeNode(map.remove(tail.prev.key));
            }
            node = new Node<>(key,val);
            map.put(key,node);
        }
        insertAfterHead(node);
    }

    public void removeNode(Node<K,V> node){
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    public void insertAfterHead(Node<K,V> node){
        node.next = head.next;
        head.next.prev = node;
        head.next = node;
        node.prev = head;
    }

    public static void main(String[] args) {
        LRU<Integer,String> lru = new LRU<>(2);
        lru.put(0,"zero");
        lru.put(1,"one");
        lru.put(2,"two");
        System.out.println(lru.get(0));
    }
}

output

null

TIPS:
面试场上,最好是不要使用JAVA提供的LinkedHashMap,因为面试官希望看到你自己手搓一个!!你能搓出来,是很加分的!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值