Java LRU cache using LinkedList

…衆ロ難τιáo~ 提交于 2020-01-06 04:25:27

问题


new to stack-overflow so please dont mind my noob way of asking this. I'm trying to implement LRU caching using a linked list, I've seen other implementations here using linkedHashMap and other data structures but for this case i'm trying to create the best optimized version using linked lists as i was asked during a technical round.

I've limited the cache size here to 3

  1. Is there any way to better optimize this LRU implementation ?
  2. Also what will be the time complexity for this implementation ? will it be of the order O(N) without considering the for-loops which are simply printing the values in the linkedList?

    public class LRU {
        public static void main(String[] args) {
    
            LinkedList list = new LinkedList();
            int[] feed = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };
            for (int i = 0; i < feed.length - 1; i++) {
                if (list.size() <= 2) {
                    list.add(feed[i]);
                    System.out.println();
                    System.out.println("Added " + feed[i]);
                    System.out.println("size of list is " + list.size());
                    System.out.print("this is list ");
                    for (int k = 0; k < list.size(); k++) {
                        System.out.print(" " + list.get(k));
                    }
                }
    
                System.out.println();
                if (list.size() >= 3) {
                    System.out.println();
                    System.out.println("feed is *" + feed[i + 1] + "*");
    
                    Integer value1 = (Integer) list.get(0);
                    Integer value2 = (Integer) list.get(1);
                    Integer value3 = (Integer) list.get(2);
                    if ((feed[i + 1] != value1) || (feed[i + 1] != value2)
                            || (feed[i + 1] != value3)) {
                        list.removeLast();
                        list.addLast(feed[i + 1]);
                        list.set(0, value2);
                        list.set(1, value3);
                        list.set(2, feed[i + 1]);
                    }
                    if (feed[i + 1] == value1) {
                        list.removeLast();
                        list.addLast(value1);
                        list.removeFirst();
                        list.addFirst(value2);
                        list.set(1, value3);
                    }
                    if (feed[i + 1] == value2) {
                        list.removeLast();
                        list.addLast(value2);
                        list.set(1, value3);
                        list.removeFirst();
                        list.addFirst(value1);
                    }
                    if (feed[i + 1] == value3) {
                        list.set(0, value1);
                        list.set(1, value2);
                    }
                }
                System.out.println("Current elements in cache at " + i);
                for (int t = 0; t < list.size(); t++) {
                    System.out.print(" " + list.get(t));
                }
                System.out.println();
            }
            System.out.println();
            System.out.println("------------------------------");
            System.out.println("current elements in cache ");
            for (int i = 0; i < list.size(); i++) {
                System.out.print(" " + list.get(i));
            }
        }
    }
    

回答1:


First of all you want to define an interface. Right now I can't see how you are supposed to use your cache or in fact what you are doing. Try to implement the following class:

class LRUCache {
    final int size;
    Cache(int size){
        this.size = size;
    }
    void put(String key, Integer value){
        //
    }
    Integer get(String key){
        //
    }
}

EDIT (Response to comment):
Whatever the problem is, first step is to define the interface (by which I don't mean Java interfaces, just something that communicates what's going on). In your case, try implementing this then.

class MRU {
    final int size;
    MRU(int size){
        this.size = size;
    }

    void put(Integer value){
        //
    }

    Set<Integer> mostRecentlyUsed(){
        //
    }
}



回答2:


I'd use

LinkedList<Integer> list = new LinkedList<>();

and instead of your implementation I'd use

if (list.size() >= 3) {
    System.out.println();
    System.out.println("feed is *" + feed[i + 1] + "*");

    // retrieve the next value from the feed
    Integer next = feed[i + 1];

    if (!list.remove(next)) {
        list.removeLast();
    }
    list.addFirst(next);

}

System.out.println("Current elements in cache at " + i);

In case the next value is in the list, it is removed and put as the first element in the list.

In case the next value is not in the list, the last element is removed and the next value is put as first element in the list.

When you then look up elements in the list, e. g. by indexOf(...) the list is searched from the newest to the oldest entry.




回答3:


Here's my linkedlist impl of LRU cache, it won't pass the leetcode judge because the linkedlist takes too long (you'll get Time Limit Exceeded).

public class LRUCache {

private Map<Integer, Integer> blocks = new HashMap<Integer,Integer>();
private LinkedList<Integer> bru = new LinkedList<Integer>();
private int capacity;
private int length;

public LRUCache(int capacity) {
    this.capacity = capacity;
    this.length = 0;
}

public int get(int key) {
    Integer value = blocks.get(key);
    if (value != null) {
        bru.remove(value);
        bru.addFirst(value);
        return value;
    }
    return -1;
}

public void set(int key, int value) {
    if (blocks.containsKey(key)) {
        bru.remove(blocks.get(key));
        blocks.put(key, value);
    } else {
        if (length >= capacity) {
            blocks.remove(bru.removeLast());
            length--;
        }

        length++;
        blocks.put(key, value);
    }
    bru.addFirst(value);
}

}



来源:https://stackoverflow.com/questions/25055210/java-lru-cache-using-linkedlist

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!