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

LFU缓存结构设计

http://www.nowcoder.com/practice/93aacb4a887b46d897b00823f30bfea1

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#include <map>
using namespace std;

class LFUCache {
  struct ListNode {
    int freq;
    int key;
    int value;
    ListNode* prev;
    ListNode* next;
    ListNode() : key(-1), value(-1), freq(0), prev(nullptr), next(nullptr) {}
    ListNode(int k, int v) : key(k), value(v), freq(1), prev(nullptr), next(nullptr) {}
  };
  struct FreqList {
    explicit FreqList(int f) : freq(f) {
      head = new ListNode;
      tail = new ListNode;

      head->next = tail;
      tail->prev = head;
    }

    void addNodeToHead(ListNode* node) {
      node->next = head->next;
      head->next->prev = node;
      node->prev = head;
      head->next = node;
    }

    void deleteNode(ListNode* node) {
      node->next->prev = node->prev;
      node->prev->next = node->next;
    }

    bool empty() const {
      return head->next == tail;
    }

    int freq;
    ListNode* head;
    ListNode* tail;
  };
public:
  LFUCache(int k) : capacity_(k), min_freq_(0) {}

  int get(int key) {
    if (hash_.count(key) == 0) {  // 不在缓存中
      return -1;
    }
    auto node = hash_[key];
    deleteNode(node);
    node->freq++;
    if (freq_map_[min_freq_]->empty()) {
      ++min_freq_;
    }
    addNodeToHead(node);
    return node->value;
  }

  void put(int key, int value) {
    if (capacity_ == 0) return; // 缓存容量为0,直接返回
    if (get(key) != -1) { // 如果在缓存中
      hash_[key]->value = value;
      return;
    }
    if (hash_.size() >= capacity_) {  // 缓存空间不足
      deleteTailNode();
    }
    auto node = new ListNode(key, value);
    min_freq_ = 1;
    addNodeToHead(node);
    hash_[key] = node;
  }

private:
  void deleteNode(ListNode* node) {
    auto lst = freq_map_[node->freq];
    lst->deleteNode(node);
  }

  void addNodeToHead(ListNode* node) {
    if (freq_map_.count(node->freq) == 0) {
      freq_map_[node->freq] = new FreqList(node->freq);
    }
    auto lst = freq_map_[node->freq];
    lst->addNodeToHead(node);
  }

  void deleteTailNode() {
    auto node = freq_map_[min_freq_]->tail->prev;
    deleteNode(node);
    hash_.erase(node->key);
  }
private:
  int capacity_;  // 缓存大小
  int min_freq_;  // 最小使用频率

  unordered_map<int/*key*/, ListNode*> hash_;
  unordered_map<int/*freq*/, FreqList*> freq_map_;
};

class Solution {
public:
  /**
   * lfu design
   * @param operators int整型vector<vector<>> ops
   * @param k int整型 the k
   * @return int整型vector
   */
  vector<int> LFU(vector<vector<int> >& operators, int k) {
    vector<int> ans;
    auto cache = new LFUCache(k);
    for (const auto& opt : operators) {
      if (opt[0] == 1) {
        cache->put(opt[1], opt[2]);
      } else {
        ans.emplace_back(cache->get(opt[1]));
      }
    }
    return ans;
  }
};

int main()
{
  Solution s;
  vector<vector<int>> vec{ {1, 1, 1}, {1, 2, 2}, {1, 3, 2}, {1, 2, 4}, {1, 3, 5}, {2, 2}, {1, 4, 4}, {2, 1} };
  auto ans = s.LFU(vec, 3);
  return 0;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务