Leetcode Design Tag

Design

// LRU Cache
// 99 ms
class LRUCache {
private:
    int capacity;
    int size;
    unordered_map cache;
    unordered_map::iterator> position;
    list visited;
    
public:
    LRUCache(int capacity) {
        this->capacity = capacity;
        this->size = 0;
    }
    
    int get(int key) {
        if (cache.find(key) != cache.end()) {
            visit(key);
            return cache[key];
        }
        return -1;
    }
    
    void put(int key, int value) {
        if (cache.find(key) != cache.end()) {
            cache[key] = value;
            visit(key);
        } else {
            if (size == capacity) 
                invalidate();
            cache[key] = value;
            visited.push_front(key);
            position[key] = visited.begin();
            size++;
        }
    }
    
    void visit(int key) {
        list::iterator iter = position[key];
        visited.erase(iter);
        visited.push_front(key);
        position[key] = visited.begin();
    }
    
    void invalidate() {
        int key = visited.back();
        visited.pop_back();
        cache.erase(key);
        position.erase(key);
        size--;
    }
};
// 86 ms
class LRUCache {
private:
    struct CacheNode {
        int key;
        int value;
        CacheNode(int k, int v) : key(k), value(v) {}
    };
    
public:
    LRUCache(int capacity) {
        this->capacity = capacity;
    }
    
    int get(int key) {
        if (cacheMap.find(key) != cacheMap.end()) {
            cacheList.splice(cacheList.begin(), cacheList, cacheMap[key]);
            cacheMap[key] = cacheList.begin();
            return cacheMap[key]->value;
        } else {
            return -1;
        }
    }
    
    void put(int key, int value) {
        if (capacity == 0)
            return;
        if (cacheMap.find(key) != cacheMap.end()) {
            cacheList.splice(cacheList.begin(), cacheList, cacheMap[key]);
            cacheMap[key] = cacheList.begin();
            cacheMap[key]->value = value;
        } else {
            if (cacheMap.size() == capacity) {
                cacheMap.erase(cacheList.back().key);
                cacheList.pop_back();
            }
            cacheList.emplace_front(CacheNode(key, value)); // emplace_front比push_front快
            cacheMap[key] = cacheList.begin();
        }
    }

private:
    int capacity;
    list cacheList;
    unordered_map::iterator> cacheMap;   
};
// LFU Cache
// 99ms
class LFUCache {
private:
    struct FrequencyListNode {
        int frequency;
        list visited;
        FrequencyListNode(int f) : frequency(f) {}
    };
    
    int capacity;
    int size;
    unordered_map cache;
    list frequencyList;
    unordered_map::iterator> index1;
    unordered_map::iterator> index2;
    
public:
    LFUCache(int capacity) {
        this->capacity = capacity;
        this->size = 0;
    }
    
    int get(int key) {
        if (cache.find(key) != cache.end()) {
            visit(key);
            return cache[key];
        }
        return -1;
    }
    
    void put(int key, int value) {
        if (capacity == 0)
            return;
        if (cache.find(key) != cache.end()) {
            cache[key] = value;
            visit(key);
        } else {
            if (size == capacity) 
                invalidate();
            cache[key] = value;
            if (frequencyList.empty() || (frequencyList.front()).frequency > 1)
                frequencyList.push_front(FrequencyListNode(1));
            (frequencyList.front()).visited.push_front(key);
            index1[key] = frequencyList.begin();
            index2[key] = (frequencyList.begin())->visited.begin();
            size++;
        }
    }
    
    void visit(int key) {
        list::iterator iter1 = index1[key];
        list::iterator iter2 = index2[key];
        int frequency = iter1->frequency;
        iter1->visited.erase(iter2);
        if (iter1->visited.empty())
            iter1 = frequencyList.erase(iter1); // Important!: erase后重新赋给iter1
        else
            iter1++;
        if (iter1 == frequencyList.end() || iter1->frequency > frequency + 1)
            iter1 = frequencyList.insert(iter1, FrequencyListNode(frequency + 1)); // Important!: insert后重新赋给iter1
        iter1->visited.push_front(key);
        index1[key] = iter1;
        index2[key] = iter1->visited.begin();
    }
    
    void invalidate() {
        int key = (frequencyList.begin())->visited.back();
        (frequencyList.begin())->visited.pop_back();
        if ((frequencyList.begin())->visited.empty())
            frequencyList.pop_front();
        cache.erase(key);
        index1.erase(key);
        index2.erase(key);
        size--;
    }
};
// 168 ms
class LFUCache {
private:
    struct CacheNode {
        int key;
        int value;
        CacheNode(int k, int v) : key(k), value(v) {}
    };
    
    struct CacheBucket {
        int frequency;
        list cacheList;
        unordered_map::iterator> cacheMap;  // map (second-layer index)
        CacheBucket(int f) : frequency(f) {}
    };
    
public:
    LFUCache(int capacity) {
        this->capacity = capacity;
    }
    
    int get(int key) {
        if (cacheMap.find(key) != cacheMap.end()) {
            list::iterator bucket = cacheMap[key];
            list::iterator node = bucket->cacheMap[key];
            int value = node->value;
            inc(bucket, key, value);
            return value;
        } else {
            return -1;
        }
    }
    
    void put(int key, int value) {
        if (capacity == 0) return;
        if (cacheMap.find(key) != cacheMap.end()) {
            list::iterator bucket = cacheMap[key];
            inc(bucket, key, value);
        } else {
            if (cacheMap.size() == capacity) {
                cache.front().cacheMap.erase(cache.front().cacheList.back().key);
                cacheMap.erase(cache.front().cacheList.back().key);
                cache.front().cacheList.pop_back();
                if (cache.front().cacheMap.empty())
                    cache.pop_front();
            }
            if (cache.empty() || cache.front().frequency > 1)
                cache.insert(cache.begin(), CacheBucket(1));
            cache.front().cacheList.push_front(CacheNode(key, value));
            cache.front().cacheMap[key] = cache.front().cacheList.begin();
            cacheMap[key] = cache.begin();
        }
    }
    
    void inc(list::iterator &bucket, int key, int value) { // frequency + 1
        int frequency = bucket->frequency;
        bucket->cacheList.erase(bucket->cacheMap[key]);
        bucket->cacheMap.erase(key);
        
        if (bucket->cacheMap.empty())
            bucket = cache.erase(bucket);
        else
            bucket++;
        if (bucket == cache.end() || bucket->frequency > frequency + 1) {
            cache.insert(bucket, CacheBucket(frequency + 1));
            bucket--;
        }
        bucket->cacheList.push_front(CacheNode(key, value));
        bucket->cacheMap[key] = bucket->cacheList.begin();
        cacheMap[key] = bucket;
    }
private:
    int capacity;
    list cache;
    unordered_map::iterator> cacheMap;  // map (first-layer index)
};
// Find Median from Data Stream
// 考虑两个优先队列(最大最小堆)
class MedianFinder {
public:
    /** initialize your data structure here. */
    MedianFinder() {}
    
    void addNum(int num) {
        if (maxpq.empty() || num <= maxpq.top()) {
            maxpq.push(num);
            if (maxpq.size() > minpq.size() + 1) {
                int median = maxpq.top();
                maxpq.pop();
                minpq.push(median);
            }
        } else {
            minpq.push(num);
            if (maxpq.size() < minpq.size()) {
                int median = minpq.top();
                minpq.pop();
                maxpq.push(median);
            }
        }        
    }
    
    double findMedian() {
        if (maxpq.size() == minpq.size())
            return ((double)maxpq.top() + (double)minpq.top()) / 2;
        else
            return maxpq.top();
    }
private:
    priority_queue maxpq; // has smaller half of the numbers
    priority_queue, greater> minpq; // has larger half of the numbers
    // Ensure that maxpq.size() == minpq.size() or maxpq.size() == minpq.size() + 1
};
// Insert Delete GetRandom O(1)
class RandomizedSet {
public:
    /** Initialize your data structure here. */
    RandomizedSet() {
        
    }
    
    /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    bool insert(int val) {
        if (pos.find(val) != pos.end())
            return false;
        elements.push_back(val);
        pos[val] = elements.size() - 1;
        return true;
    }
    
    /** Removes a value from the set. Returns true if the set contained the specified element. */
    bool remove(int val) {
        if (pos.find(val) == pos.end())
            return false;
        if (pos[val] < elements.size() - 1) {
            int replace_val = elements.back();
            pos[replace_val] = pos[val];
            elements[pos[val]] = replace_val;
        }
        pos.erase(val);
        elements.pop_back();
        return true;
    }
    
    /** Get a random element from the set. */
    int getRandom() {
        return elements[rand() % elements.size()];
    }
private:
    vector elements;
    unordered_map pos;
};
// Insert Delete GetRandom O(1) - Duplicates allowed
// 56 ms
class RandomizedCollection {
private:
    struct CacheNode {
        int frequency;
        list pos;
        unordered_map::iterator> posCache;
        CacheNode() {} // Important!: 要保留默认构造函数
        CacheNode(int f, int p) {
            frequency = f;
            pos.push_back(p);
            posCache[p] = --pos.end(); // Important!: 没有pos.end() - 1,pos.end()--也是错的
        }
        void inc(int p) {
            frequency++;
            pos.push_back(p);
            posCache[p] = --pos.end();
        }
        int dec() {
            frequency--;
            int p = pos.back();
            pos.pop_back();
            posCache.erase(p);
            return p;
        }
        void update(int p, int q) {
            pos.erase(posCache[p]);
            posCache.erase(p);
            pos.push_back(q);
            posCache[q] = --pos.end();
        }
    };
    
public:
    /** Initialize your data structure here. */
    RandomizedCollection() {
        size = 0;
    }
    
    /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
    bool insert(int val) {
        elements.push_back(val);
        if (cache.find(val) != cache.end()) {
            cache[val].inc(size++);
            return false;
        } else {
            cache[val] = CacheNode(1, size++); // 因为这里会先调用默认构造函数,再调用operator =
            return true;
        }
    }
    
    /** Removes a value from the collection. Returns true if the collection contained the specified element. */
    bool remove(int val) {
        if (cache.find(val) == cache.end())
            return false;
        int p = cache[val].dec();
        if (cache[val].frequency == 0)
            cache.erase(val);
        if (p < size - 1) {
            int replace_val = elements[size - 1];
            elements[p] = replace_val;
            cache[replace_val].update(size - 1, p);
        }
        elements.pop_back();
        size--;
        return true;
    }
    
    /** Get a random element from the collection. */
    int getRandom() {
        return elements[rand() % size];
    }

private:
    unordered_map cache;
    vector elements;
    int size;
};
// All O`one Data Structure
class AllOne {
public:
    struct CacheNode {
        int value;
        list keys;
        CacheNode() {}
        CacheNode(int v, string key) : value(v) { keys.push_back(key); }
    };
    /** Initialize your data structure here. */
    AllOne() {
        
    }
    
    /** Inserts a new key  with value 1. Or increments an existing key by 1. */
    void inc(string key) {
        if (index1.find(key) == index1.end()) {
            if (cache.empty() || cache.front().value > 1)
                cache.push_front(CacheNode(1, key));
            else
                cache.front().keys.push_front(key);
            index1[key] = cache.begin();
            index2[key] = cache.front().keys.begin();
        } else {
            list::iterator iter1 = index1[key];
            list::iterator iter2 = index2[key];
            int value = iter1->value;
            iter1->keys.erase(iter2);
            if (iter1->keys.empty())
                iter1 = cache.erase(iter1);
            else
                iter1++;
            if (iter1 == cache.end() || iter1->value > value + 1)
                iter1 = cache.insert(iter1, CacheNode(value + 1, key));
            else
                iter1->keys.push_front(key);
            index1[key] = iter1;
            index2[key] = iter1->keys.begin();
        }
    }
    
    /** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */
    void dec(string key) {
        if (index1.find(key) != index1.end()) {
            list::iterator iter1 = index1[key];
            list::iterator iter2 = index2[key];
            int value = iter1->value;
            iter1->keys.erase(iter2);
            if (iter1->keys.empty())
                iter1 = cache.erase(iter1);
            if (value == 1) {
                index1.erase(key);
                index2.erase(key);
                return;
            }
            if (iter1 == cache.begin()) {
                cache.push_front(CacheNode(value - 1, key));
                iter1 = cache.begin();
            } else if ((--iter1)->value < value - 1) {
                iter1 = cache.insert(++iter1, CacheNode(value - 1, key));
            } else {
                iter1->keys.push_front(key);
            }
            index1[key] = iter1;
            index2[key] = iter1->keys.begin();
        }
    }
    
    /** Returns one of the keys with maximal value. */
    string getMaxKey() {
        return cache.back().keys.front();
    }
    
    /** Returns one of the keys with Minimal value. */
    string getMinKey() {
        return cache.front().keys.front();
    }
private:
    list cache;
    unordered_map::iterator> index1;
    unordered_map::iterator> index2;
};
// Peeking Iterator
// Since Iterator has a copy constructor, we can just use it
// Below is the interface for Iterator, which is already defined for you.
// **DO NOT** modify the interface for Iterator.
class Iterator {
    struct Data;
    Data* data;
public:
    Iterator(const vector& nums);
    Iterator(const Iterator& iter);
    virtual ~Iterator();
    // Returns the next element in the iteration.
    int next();
    // Returns true if the iteration has more elements.
    bool hasNext() const;
};

class PeekingIterator : public Iterator {
public:
    PeekingIterator(const vector& nums) : Iterator(nums) {
        // Initialize any member here.
        // **DO NOT** save a copy of nums and manipulate it directly.
        // You should only use the Iterator interface methods.
    }

    // Returns the next element in the iteration without advancing the iterator.
    int peek() {
        return Iterator(*this).next();
    }

    // hasNext() and next() should behave the same as in the Iterator interface.
    // Override them if needed.
    int next() {
        return Iterator::next();
    }

    bool hasNext() const {
        return Iterator::hasNext();
    }
};
// Min Stack
class MinStack {
private:
    struct StackNode {
        int value;
        int min;
        StackNode *next;
        StackNode(int value, int min, StackNode *next) : value(value), min(min), next(next) {}
    };
    StackNode *head;
public:
    /** initialize your data structure here. */
    MinStack() {
        head = NULL;
    }
    void push(int x) {
        if (head == NULL)
            head = new StackNode(x, x, NULL);
        else {
            head = new StackNode(x, min(x, getMin()), head);
        }
    }
    void pop() {
        if (head) {
            StackNode *newhead = head->next;
            free(head);
            head = newhead;
        }
    }
    int top() {
        if (head)
            return head->value;
    }
    int getMin() {
        if (head)
            return head->min;
    }
};
class MinStack {
private:
    stack s1;
    stack s2;
public:
    void push(int x) {
        s1.push(x);
        if (s2.empty() || x <= getMin())  s2.push(x);       
    }
    void pop() {
        if (s1.top() == getMin())  s2.pop();
        s1.pop();
    }
    int top() {
        return s1.top();
    }
    int getMin() {
        return s2.top();
    }
};
// Implement Queue using Stacks
class MyQueue {
public:
    /** Initialize your data structure here. */
    MyQueue() {   
    }
    /** Push element x to the back of queue. */
    void push(int x) {
        input.push(x);
    }
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        int result = peek();
        output.pop();
        return result;
    }
    /** Get the front element. */
    int peek() {
        if (output.empty())
            transfer();
        return output.top();
    }
    /** Returns whether the queue is empty. */
    bool empty() {
        return input.empty() && output.empty();
    }
    void transfer() {
        while (!input.empty()) {
            output.push(input.top());
            input.pop();
        }
    }
private:
    stack input, output;
};
// Implement Stack using Queues
class MyStack {
public:
    /** Initialize your data structure here. */
    MyStack() { 
    }
    /** Push element x onto stack. */
    void push(int x) {
        q.push(x);
    }
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        queue p;
        while (q.size() > 1) {
            p.push(q.front());
            q.pop();
        }
        int result = q.front();
        q = p;
        return result;
    }
    /** Get the top element. */
    int top() {
        int result;
        queue p;
        while (!q.empty()) {
            result = q.front();
            p.push(q.front());
            q.pop();
        }
        q = p;
        return result;
    }
    /** Returns whether the stack is empty. */
    bool empty() {
        return q.empty();
    }
private:
    queue q;
};
// Flatten Nested List Iterator
class NestedIterator {
public:
    NestedIterator(vector &nestedList) {
        initialize(nestedList);
        pos = 0;
    }

    int next() {
        return vec[pos++];
    }

    bool hasNext() {
        return pos != vec.size();
    }
private:
    vector vec;
    int pos;
    void initialize(vector &nestedList) {
        for (NestedInteger i : nestedList) {
            if (i.isInteger())
                vec.push_back(i.getInteger());
            else
                initialize(i.getList());
        }
    }
};
class NestedIterator {
public:
    NestedIterator(vector &nestedList) {
        if (!nestedList.empty()) {
            s.push(make_pair(nestedList.begin(), nestedList.end()));
            adjust();
        }
    }

    int next() {
        vector::iterator ib = s.top().first, ie = s.top().second, iter;
        s.pop();
        int res = ib->getInteger();
        ib++;
        if (ib != ie)
            s.push(make_pair(ib, ie));
        adjust();
        return res;
    }

    bool hasNext() {
        return !s.empty();
    }
private:
    stack::iterator, vector::iterator>> s;
    void adjust() {
        while (!s.empty() && !s.top().first->isInteger()) {
            vector::iterator ib = s.top().first, ie = s.top().second, iter;
            s.pop();
            iter = ib;
            ib++;
            if (ib != ie)
                s.push(make_pair(ib, ie));
            if (!iter->getList().empty())
                s.push(make_pair(iter->getList().begin(), iter->getList().end()));
        }
    }
};
class NestedIterator {
public:
    NestedIterator(vector &nestedList) {
        s.push(make_pair(nestedList.begin(), nestedList.end()));
        adjust();
    }

    int next() {
        int res = s.top().first->getInteger();
        s.top().first++;
        adjust();
        return res;
    }

    bool hasNext() {
        return !s.empty();
    }
private:
    stack::iterator, vector::iterator>> s;
    void adjust() {
        while (!s.empty()) {
            if (s.top().first == s.top().second) {
                s.pop();
            } else {
                if (s.top().first->isInteger())
                    break;
                vector::iterator iter = s.top().first;
                s.top().first++;
                s.push(make_pair(iter->getList().begin(), iter->getList().end()));
            }
        }
    }
};
// Binary Search Tree Iterator
class BSTIterator {
public:
    BSTIterator(TreeNode *root) {
        TreeNode *p = root;
        while (p) {
            s.push(p);
            p = p->left;
        }
    }
    /** @return whether we have a next smallest number */
    bool hasNext() {
        return !s.empty();
    }
    /** @return the next smallest number */
    int next() {
        int res = s.top()->val;
        TreeNode *p = s.top()->right;
        if (p) {
            while (p) {
                s.push(p);
                p = p->left;
            }
        } else {
            p = s.top();
            s.pop();
            while (!s.empty() && p == s.top()->right) {
                p = s.top();
                s.pop();
            }
        }
        return res;
    }
private:
    stack s;
};
class BSTIterator {
public:
    BSTIterator(TreeNode *root) {
        TreeNode *p = root;
        while (p) {
            s.push(p);
            p = p->left;
        }
    }
    /** @return whether we have a next smallest number */
    bool hasNext() {
        return !s.empty();
    }
    /** @return the next smallest number */
    int next() {
        int res = s.top()->val;
        TreeNode *p = s.top()->right;
        s.pop();
        while (p) {
            s.push(p);
            p = p->left;
        }
        return res;
    }
private:
    stack s;
};
// Flatten 2D Vector
class Vector2D {
public:
    Vector2D(vector>& vec2d) {
        x = vec2d.begin();
        end = vec2d.end();
    }
    int next() {
        return (*x)[y++];
    }
    bool hasNext() {
        while (x != end && y == (*x).size()) {
            ++x; 
            y = 0;
        }
        return x != end;
    }
private:
    vector>::iterator x, end;
    int y = 0;
};

你可能感兴趣的:(Leetcode Design Tag)