Leetcode LRU Cache

LRU Cache

  Total Accepted: 14047  Total Submissions: 103807 My Submissions

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

Have you been asked this question in an interview?

看到网上说这道题目要用双向链表+map来做,我只用了双向链表,getKey复杂度是O(n),set(key,value)当中包含get(key)。我是用了链表的头结点和尾结点,头结点指向链表的第一个元素,尾结点指向链表的最后一个元素。我用java写的一次性过了getKey和setKey的复杂度都是O(n)
Submit Time Status Run Time Language
3 hours, 14 minutes ago Accepted 1188 ms java

//双向链表节点定义
class Node
<span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px;">{</span>
	int key;
	int value;
	int time;
	Node pre;
	Node next;
	Node(){}
	Node(int k,int v)
	{
		key = k;
		value = v;
	}
}
public class LRUCache{
	int cap;
	Node head;
	Node tail;
	int len;
	public LRUCache(int capacity){
		head = new Node();
		tail = new Node();
		tail.next = head;
		cap = capacity;
		len = 0;
	}
//下面是测试代码
	/*
	public static void main(String[] args) {
		LRUCache lru = new LRUCache(10);
		for(int i=0;i<1000;i++){
			int tmp =(int) (Math.random()*100);
			int key = tmp+(int) (Math.random()*100);
			int value = tmp-(int) (Math.random()*80);
			if(tmp>50)
			{
				System.out.print(i+":get key"+key+"--");
				System.out.println(lru.get(key));
				if(lru.get(key)==-1)
				{
					System.out.println(i+":set key"+key+"--"+value);
					lru.set(key, value);
				}
			}else {
				System.out.println(i+":set key"+key+"--"+value);
				lru.set(key, value);
			}
		}
	}*/
	public int get(int key){
		int i = 0;
		Node h = head.next;
		Node pre = head.next;
		while(h!=null)
		{
			if(h.key==key)
			{
				//find the key and move it to head.next;
				if(h!=head.next)
				{
					// tail.next is the h ,h is the last element
					if(tail.next==h)
					{
						tail.next = h.pre;
					}
					//cut it out
					pre.next = h.next;
					if(h.next!=null)
					{
						h.next.pre = h.pre;
					}
					// put it after head;
					h.next = head.next;
					head.next.pre = h;
					h.pre = head;
					head.next = h;
				}
				return h.value;
			}
			pre = h;
			h = h.next;
		}
		return -1;
	}

	public void set(int key,int value){
<span style="white-space:pre">		</span>//find the key just use doubledlinked list
		if(get(key)==-1)
		{
			if(len==cap && len>0)
			{
				tail.next = tail.next.pre;
				//I should write one more next
				tail.next.next.pre = null;
				tail.next.next = null;
				len--;
			}
			Node node = new Node(key,value);
			if(head.next!=null)
			{
				head.next.pre = node;
			}
				node.next = head.next;
				node.pre = head;
				head.next = node;
				//tail.next is head;
				if(tail.next==head)
				{
					tail.next = tail.next.next;
				}
				len++;
		}else
		{
			head.next.value = value;
		}
		return ;
	}
}


之前用C++写过,C++先前只用双向链表,超时了,不知道是否是代码有问题。然后加了hashMap通过了。复杂度是O(log(n));
2 months, 1 week agoLRU CacheAccepted380 mscpp

/**
 * Two method can solved this problem. First use doubleLinkedList, the get time complexity is O(n), and the set complexity is O(1);
 * I don't know whether I can pass just use DoubleLinkedList. If I cannot pass, then I will add hashMap in it. The time complexity with
 * hashMap is O(1);
 * I use the doubleLinkedList but get time limit exceed, I must use hashMap;
 */
struct DoubleLinkedList
{
    int key;
    int val;
    struct DoubleLinkedList * next;
    struct DoubleLinkedList * before;
    DoubleLinkedList(int x,int y) : key(x),val(y), next(NULL), before(NULL) {}
};

class LRUCache{
    int cap;
    DoubleLinkedList *head,*end;
    int elements;
    map<int,DoubleLinkedList *> myMap;
public:
    LRUCache(int capacity) {
        cap = capacity;
        head = NULL;
        end =NULL;
        elements = 0;
    }
    
    int get(int key) {
        DoubleLinkedList *p1 =NULL,*p2 = NULL,*p3=NULL;
        if(myMap.count(key))
        {
            if(end->key==key)
            {
                if(end->before!=NULL)
                {
                    end = end->before;
                }
            }
            p1 = myMap[key];
            p2 = p1->before;
            p3 = p1->next;
            if(p2!=NULL) // not the head point
            {
                p2->next = p3;
                if(p3!=NULL)
                {
                    p3->before = p2;
                }
				if(p2->before==NULL)
				{
					p2->before = p1;
				}
                p1->next = head;
                p1->before = NULL;
                if(head!=NULL)
                {  //***************important
                    head->before = p1;
                }
                head = p1;
            }
            return head->val;
        }else
        {
            return -1;
        }
    }
    
    void set(int key, int value) {
         DoubleLinkedList *p1 =NULL,*p2 = NULL,*p3=NULL;
          // need add new cache
        if(myMap.count(key))
        {
            p1 = myMap[key];
            p1->val = value;
            get(key);
            return ;
        }
        p1 = new DoubleLinkedList(key,value);
        p2 = head;
        int i=1;
        if(cap==0)
        {
            return ;
        }
        // delete the element in the tail
        if(elements==cap)
        {
            // the capacity is just one;
            if(cap==1)
            {
                myMap.erase(end->key);
                free(head);
                head = p1;
                end = p1;
                myMap[key] = p1;
                return;
            }
                // if there is a problem
            myMap.erase(end->key);
			p3 = end;
			end = end->before;
			end->next = NULL; //***************important
            free(p3);
            elements--;
        }
        if(elements==0)
        {
            head = p1;
            end = p1;
            elements++;
            myMap[key] = head;
            return ;
        }
        p1->next = head;
        head->before = p1;
        head = p1;
        myMap[key] = p1;
		if(elements==1)
		{
			end->before = head;
		}
        elements++;
        return;
    }
    
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值