Amazon Interview Question
InternsCountry: India
As bob said, use a min heap to cache the Jobs.
1. When new Job is added into the cache,
If Heap size is max cache size, remove root and replace with newly added Job. Use current timestamp as node value for comparison. With that new node will move down to leaf node.
2. When an item is accessed from the cache, update it's time stamp to the current time and that will cause it to move down.
However this will not solve the problem of searching an element with O(1) from cache. Therefore an additional Map might be required to point into Heap for efficient retrieval
#include <queue>
#include <stdexcept>
#include <unordered_map>
using namespace std;
class LRU
{
public:
LRU(int c = 0) : cap(c), size(0), time(0) {}
int get(int key)
{
if (vlist.cunt(key) == 0) throw logic_error("can't find key");
return vlist[key];
}
void set(int key, int val)
{
if (vlist.count(key) == 0)
{
if (size == cap)
{
while (true)
{
P p = que.top(); que.pop(); int t = p.first, k = p.second;
if (t == tlist[k])
{
tlist.erase(key); vlist.erase(key); break;
}
}
}
else ++size;
}
vlist[key] = val;
tlist[key] = ++time;
que.push(P(time, key));
}
private:
typedef pair<int, int> P;
int time, size, cap;
proority_queue<P> que;
unordered_map<int, int> tlist, vlist;
};
#include <queue>
#include <stdexcept>
#include <unordered_map>
using namespace std;
class LRU
{
public:
LRU(int c = 0) : cap(c), size(0), time(0) {}
int get(int key)
{
if (vlist.cunt(key) == 0) throw logic_error("can't find key");
return vlist[key];
}
void set(int key, int val)
{
if (vlist.count(key) == 0)
{
if (size == cap)
{
while (true)
{
P p = que.top(); que.pop(); int t = p.first, k = p.second;
if (t == tlist[k])
{
tlist.erase(key); vlist.erase(key); break;
}
}
}
else ++size;
}
vlist[key] = val;
tlist[key] = ++time;
que.push(P(time, key));
}
private:
typedef pair<int, int> P;
int time, size, cap;
proority_queue<P> que;
unordered_map<int, int> tlist, vlist;
};
#include <queue>
#include <stdexcept>
#include <unordered_map>
using namespace std;
class LRU
{
public:
LRU(int c = 0) : cap(c), size(0), time(0) {}
int get(int key)
{
if (vlist.cunt(key) == 0) throw logic_error("can't find key");
return vlist[key];
}
void set(int key, int val)
{
if (vlist.count(key) == 0)
{
if (size == cap)
{
while (true)
{
P p = que.top(); que.pop(); int t = p.first, k = p.second;
if (t == tlist[k])
{
tlist.erase(key); vlist.erase(key); break;
}
}
}
else ++size;
}
vlist[key] = val;
tlist[key] = ++time;
que.push(P(time, key));
}
private:
typedef pair<int, int> P;
int time, size, cap;
proority_queue<P> que;
unordered_map<int, int> tlist, vlist;
};
public class LRUCache<K,V> {
int capacity;
LRUCache( int capacity ) {
this.capacity = capacity;
}
static class Element<K,V> implements Comparable<Element<K,V>>{
Element(K k, V v) {
this.k = k;
this.v = v;
timestamp = System.currentTimeMillis();
}
long timestamp;
K k;
V v;
public int compareTo(Element<K,V> other) {
return Long.compare(this.timestamp, other.timestamp);
}
public boolean equals(Object obj ) {
if ( !( obj instanceof Element ) ) return false;
Element<K,V> other =(Element<K,V>)obj;
return other.k.equals(this.k);
}
public int hashCode() {
return k.hashCode();
}
}
PriorityQueue<Element<K,V>> queue = new PriorityQueue<Element<K,V>>();
Map<K,Element<K,V>> elements = new HashMap<K,Element<K,V>>();
public V get(K k) {
if (elements.containsKey(k)) {
Element<K, V> e = elements.get(k);
queue.remove(e);
e.timestamp = System.currentTimeMillis();
queue.add(e);
return e.v;
} else {
return null;
}
}
void set(K k, V v) {
if (elements.containsKey(k)) {
Element<K, V> e = elements.get(k);
queue.remove(e);
e.v = v;
e.timestamp = System.currentTimeMillis();
queue.add(e);
}
else if ( queue.size() + 1 > capacity ) {
Element<K,V> e = queue.remove();
elements.remove(e.k);
Element<K,V> newE = new Element<K,V>(k,v);
queue.add(newE);
elements.put(k, newE);
}
else {
Element<K,V> newE = new Element<K,V>(k,v);
queue.add(newE);
elements.put(k, newE);
}
}
void remove (K k) {
if (elements.containsKey(k)) {
Element<K, V> e = elements.get(k);
queue.remove(e);
elements.remove(k);
}
}
public static void main(String[] args) {
}
}
Use min-heap to store the least recently used element at the top. When a new element arrives, replace the topmost element with it and sift it down.
- bob22 June 13, 2015