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

设计LRU缓存结构

http://www.nowcoder.com/practice/e3769a5f49894d49b871c09cadd13a61

本文仅用于本人记录

好家伙,第一次见这题,我整整弄了两小时。。。。。

一开始想着只用一个哈希表,题目的set和get都是o(1)的,可是还得处理当hashmap缓存大于k个键值对的时候清理掉最久远没set更新或者没get访问的键值对呀!所以我第一想到的就是对每个元素加一个power,代表建立该键值对的时间,越大说明越新,越小说明很久没更新/访问了。可是这样每次set和get就是o(n)了,严重超时。。。。
然后看题解,牛逼啊,用哈希表实现set和get的o(1);然后用一个链表真实存储这些数据节点(哈希表本身不创造数据节点)。这样每次操作了set或者get就将对应节点(通过哈希表可以快速o(1)地找到那个节点)挪到链表头结点后第一位去,表示最新。删除也只是要移出哈希表的那个对应节点键值对就行了,真实的节点在链表其实删不删都无所谓。
当初我还不信邪,硬是要单向链表。。。结果发现还是双向链表简洁。

import java.util.*;

 class Listnode{
    int key;
    int value;
    Listnode next = null;
    Listnode prev = null;
 }
public class Solution {
    /**
     * lru design
     * @param operators int整型二维数组 the ops
     * @param k int整型 the k
     * @return int整型一维数组
     */
    public int[] LRU (int[][] operators, int k) {
        // write code here
        HashMap<Integer,Listnode> hashMap = new HashMap<>();
        Listnode head = new Listnode();
        ArrayList<Integer> arrays = new ArrayList<>();
        for(int i = 0;i < operators.length;i++){
            if(hashMap.size() > k){
                Listnode iter = head;
                for(int j = 0;j < k;j++){
                    iter = iter.next;
                }
                hashMap.remove(iter.next.key);
                iter.next.prev = null;
                iter.next = null;
            }
            if(operators[i][0] == 1){
                if(hashMap.get(operators[i][1]) != null){
                    Listnode node = hashMap.get(operators[i][1]);
                    node.value = operators[i][2];
                    hashMap.put(operators[i][1],node);
                    moveToHead(head,node);
                }
                else{
                    Listnode node = new Listnode();
                    node.key = operators[i][1];
                    node.value = operators[i][2];
                    hashMap.put(operators[i][1],node);
                    moveToHead(head,node);
                }
            }
            else if(operators[i][0] == 2){
                if(hashMap.get(operators[i][1]) != null){
                    arrays.add(hashMap.get(operators[i][1]).value);
                    moveToHead(head,hashMap.get(operators[i][1]));
                }else{
                    arrays.add(-1);
                }
            }
        }
        int[] result = new int[arrays.size()];
        int i = 0;
        for (Integer array : arrays) {
            result[i++] = array;
        }
        return result;
   }
    void moveToHead(Listnode head,Listnode node){
        if(node.next != null && node.prev != null){
            node.next.prev = node.prev;
            node.prev.next = node.next;
        }

        if(head.next != null){
            head.next.prev = node;
        }
        node.next = head.next;
        head.next = node;
        node.prev = head;
    }
}
全部评论

相关推荐

点赞 评论 收藏
分享
死在JAVA的王小美:哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈,我也是,让我免了一轮,但是硬气拒绝了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务