程序员代码面试指南刷题--第九章.设计LRU缓存结构

题目描述
设计LRU缓存结构,该结构在构造时确定大小,假设大小为K,并有如下两个功能

set(key, value):将记录(key, value)插入该结构
get(key):返回key对应的value值

[要求]

set和get方法的时间复杂度为O(1)
某个key的set或get操作一旦发生,认为这个key的记录成了最常使用的。
当缓存的大小超过K时,移除最不经常使用的记录,即set或get最久远的。

输入描述:

第一行两个个整数N, K,表示操作数量以及缓存结构大小
接下来N行,第一行一个整数opt表示操作类型。
若opt=1,接下来两个整数x, y,表示set(x, y)
若opt=2,接下来一个整数x,表示get(x),若x未出现过或已被移除,则返回-1

输出描述:

对于每个操作2,输出一个答案

示例1

输入

6 3
1 1 1
1 2 2
1 3 2
2 1
1 4 4
2 2

输出

1
-1

解法一:双端链表+两个map

import java.io.*;
import java.util.*;
public class Main{
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    public static void main(String[] args) throws Exception{
        
        String[] ss = br.readLine().trim().split(" ");
        int nums = Integer.parseInt(ss[0]);
        int capcity = Integer.parseInt(ss[1]);
        fun(nums,capcity);
    }
    public static void fun(int nums,int capcity) throws IOException {
    	MyCache<Integer,Integer> mycache = new MyCache(capcity);
    	for(int i=0;i<nums;i++) {
    		String[] info = br.readLine().trim().split(" ");
    		if("1".equals(info[0])) {
    			int key = Integer.parseInt(info[1]);
    			int val = Integer.parseInt(info[2]);
    			mycache.set(key, val);
    		}else {
    			int key = Integer.parseInt(info[1]);
    			Integer res = mycache.get(key);
    			System.out.println(res==null?-1:res);
    		}
    	}
    }
}
class Node<V>{
    V val;
    Node<V> last;
    Node<V> next;
    public Node(V val){
        this.val = val;
    }
}
class DoubleLink<V>{
    Node<V> head;
    Node<V> tail;
    public DoubleLink(){
        head = null;
        tail = null;
    }
    public void addNode(Node<V> node){
        if(node==null) return;
        if(tail==null){
            head = node;
            tail = node;
        }else{
            tail.next = node;
            node.last = tail;
            tail = node;
        }
    }
    public void moveNodeToTail(Node<V> node){
        if(node==null) return;
        if(node==tail) return;
        if(node==head){
            head = head.next;
            head.last = null;
        }else {
            node.last.next = node.next;
            node.next.last = node.last;
        }
        tail.next = node;
        node.last = tail;
        tail = node;
        node.next = null;
    }
    public Node<V> removeHead(){
        if(head==null) return null;
        Node<V> res = head;
        if(tail==head){
            head = null;
            tail = null;
        }else{
            head = head.next;
            head.last = null;
            res.next = null;
        }
        return res;
    }
}
class MyCache<K,V>{
    HashMap<K,Node<V>> keyNode;
    HashMap<Node<V>,K> nodeKey;
    int capacity;
    DoubleLink<V> link;
    public MyCache(int cap){
        keyNode = new HashMap<>();
        nodeKey = new HashMap<>();
        this.capacity = cap;
        link = new DoubleLink();
    }
    public V get(K key){
        if(keyNode.containsKey(key)){
            Node<V> res = keyNode.get(key);
            link.moveNodeToTail(res);
            return res.val;
        }
        return null;
    }
    public void set(K key,V val){
        if(keyNode.containsKey(key)){
            Node<V> node = keyNode.get(key);
            node.val = val;
            link.moveNodeToTail(node);
        }else{
            Node<V> node = new Node<V>(val);
            keyNode.put(key,node);
            nodeKey.put(node,key);
            link.addNode(node);
            if(keyNode.size()==capacity+1){
                removeMostUnused();
            }
        }
    }
    public void removeMostUnused(){
        Node<V> head = link.removeHead();
        K key = nodeKey.get(head);
        nodeKey.remove(head);
        keyNode.remove(key);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值