当前位置: 首页 > news >正文

做单机游戏破解的网站北京seo课程

做单机游戏破解的网站,北京seo课程,怎样在微信上开店卖东西,做网站 空间还是服务器力扣题目链接 题意:本题的题意就是希望我们设计一个满足 LRU 缓存的数据结构,LRU即最近最少使用。 需要我们实现 get 和 put 方法,即从缓存中获取值和设置缓存中值的方法。 还有一个约束条件就是缓存应当有容量限制,如果实现 put …

力扣题目链接

题意:本题的题意就是希望我们设计一个满足 LRU 缓存的数据结构,LRU即最近最少使用。
需要我们实现 get 和 put 方法,即从缓存中获取值和设置缓存中值的方法。
还有一个约束条件就是缓存应当有容量限制,如果实现 put 方法的时候,没有空闲的空间的话,需要淘汰一个最久没有使用的 key
同时要求 get 和 put 的时间复杂度是 O(1)

其实关于 LRU 最类似的一种应用就是浏览器记录,随着我们打开的浏览器越来越多,浏览历史表就会越来越长,如果我们想要打开某个浏览页面,也会直接从缓存中读取,并且由于我们打开了历史记录中的某个浏览页面,它会成为最新的那条记录。

文章目录

  • 测试用例解读
  • 总体代码
  • 简洁实现
    • 类成员变量
    • 构造函数
    • get 方法
    • put 方法

测试用例解读

可以直接看 B 站视频 :【大厂面试官让我手写LRU缓存,还好提前抱了佛脚,春招有希望了】(具体位置从 3:00开始)

首先我们一个一个解决上面提出的几个问题:

  • 首先关于我们要求的 get 查询方法,很直观的一个想法就是使用 map 来进行实现,不过他只能实现查询时间复杂度为 O(1),但是由于 map 本身是无序的,所以我们希望他能够有新旧顺序的信息。
  • 很直观的思路,我们每次新建一个键值对的时候,就把这个 key-value 放入一个链表的头,我们每次存入新的节点,我们就把其作为新的头。这样我们链表的头部永远都是那个最新的 key-value;链表的尾部就是最久未使用的键值对
  • 但是我们仍然有一个很重要的问题无法实现:如果我们查询了某个 key-value ,并且该节点在链表的中间位置,那么我们就不能及时得将该节点放到链表的头部。因为我们的 map 是以 key-value 来进行存取的,所以我们不能在链表中及时找到对应的节点
  • 为了应对上面的情况,有一个比较好的思路就是,当我们存储节点时,map 中的 key 就是该节点的键,map 中的 value 就是该节点所在链表的节点(ListNode*)。通过这样的方法,我们可以快速定位到链表节点,而不需要根据别的信息进行遍历。
  • 根据以上的要求,我们可以知道,使用单向链表是无法实现上述想法的,因为我们的节点是需要往前移动到链表头部,所以这里的数据结构使用双向链表。

总上所述,我们的代码雏形就出来了。

总体代码

  • 首先定义双向链表的节点结构:每个结构包括 key-value 的值和 prev 和 next 指针,并且定义两个构造函数
struct Node {int key, value;Node *prev, *next;Node() : key(0), value(0), prev(nullptr), next(nullptr) {}Node(int key, int value) : key(key), value(value), prev(nullptr), next(nullptr) {}
};
  • 下面来实现 LRU 缓存:定义链表的虚拟头、尾节点;哈希表来存储 key 和 双向链表节点 的映射关系;最后是我们的容量大小,以及当前已使用的大小。
class LRUCache {
private:std::unordered_map<int, Node*> hashMap_;int capacity_, size_;Node *dummyHead_, *dummyTail_;
};
  • 实现 LRUCache 的构造函数:
class LRUCache {
private:...
public: LRUCache(int capacity) : capacity_(capacity), size_(0) {dummyHead_ = new Node();dummyTail_ = new Node();dummyHead_->next = dummyTail_;dummyTail_->prev = dummyHead_;}
  • 接下来我们来实现从链表中删除节点和插入节点到链表头的方法,该方法是其中的 get 和 put 方法中的重要:
    void removeNode(Node* node) {node->prev->next = node->next;node->next->prev = node->prev;}// 在头节点处插入一个 nodevoid addNodeToHead(Node* node) {node->prev = dummyHead_;node->next = dummyHead_->next;dummyHead_->next->prev = node;dummyHead_->next = node;}
  • 接下来实现重要的 get 方法:首先我们需要确定节点时候在哈希表中:
    int get(int key) {if (hashMap_.find(key) != hashMap_.end()) {Node* node = hashMap_[key];removeNode(node);addNodeToHead(node);return node->value;}return -1;}
  • 随后是设置节点的值:如果该节点在哈希表中存在的话,我们就重新设置其节点的值,随后更新其位置在最前面;如果不存在的话,说明要插入一个新的节点,我们首先要判断一下容量,如果容量达到了上限,我们就需要从链表的尾部淘汰一个节点,然后在进行插入
    void put(int key, int value) {if (hashMap_.find(key) != hashMap_.end()) {Node* node = hashMap_[key];node->value = value;removeNode(node);addNodeToHead(node);} else {if (size_ == capacity_) {Node* removed = dummyTail_->prev;hashMap_.erase(removed->key);removeNode(removed);delete removed;size_--;}Node* node = new Node(key, value);addNodeToHead(node);hashMap_[key] = node;size_++;}}

简洁实现

这里介绍一个简介实现,如下:

class LRUCache {
public:LRUCache(int capacity) : capacity_(capacity) {}int get(int key) {auto it = cacheMap.find(key);if (it == cacheMap.end()) {return -1; // Key not found} else {// Move the accessed (key, value) pair to the front of the cacheListcacheList.splice(cacheList.begin(), cacheList, it->second);return it->second->second;}}void put(int key, int value) {auto it = cacheMap.find(key);if (it != cacheMap.end()) {// Key already exists, update the value and move it to the frontit->second->second = value;cacheList.splice(cacheList.begin(), cacheList, it->second);} else {if (cacheList.size() == capacity_) {// Cache is full, remove the least recently used itemauto last = cacheList.back();cacheMap.erase(last.first);cacheList.pop_back();}// Insert the new key-value pair at the frontcacheList.emplace_front(key, value);cacheMap[key] = cacheList.begin();}}private:int capacity_;std::list<std::pair<int, int>> cacheList; // Stores the (key, value) pairsstd::unordered_map<int, std::list<std::pair<int, int>>::iterator> cacheMap; // Maps key to the corresponding iterator in cacheList
};

类成员变量

首先定义一个类成员变量:

class LRUCache {
private:int capacity_;std::list<std::pair<int, int>> cacheList_; // Stores the (key, value) pairsstd::unordered_map<int, std::list<std::pair<int, int>>::iterator> cacheMap_; // Maps key to the corresponding iterator in cacheList
};

这里的 cacheList 即我们之前所维护的那个双向链表;
cacheMap 就是我们之前维护的那个 hashMap ,key 是键值, value 是我们之前的链表节点。

在此之前,我们自己定义个用于缓存的节点,但是我们可以直接使用 std::pair<int, int> 来代替我们自己构造的类;

除此之外:std::pair<int, int>>::iterator 是一个类型声明,用于表示指向 std::list<std::pair<int, int>> 中元素的迭代器,这个迭代器类型可以用来遍历或访问 std::list 容器中的元素。

接下来我们开始进行主要成员方法的实现:

构造函数

class LRUCache {
public:LRUCache(int capacity) : capacity_(capacity) {}
private:...
};

get 方法

    int get(int key) {auto it = cacheMap_.find(key);if (it == cacheMap_.end()) {return -1; // Key not found} else {// Move the accessed (key, value) pair to the front of the cacheListcacheList_.splice(cacheList_.begin(), cacheList_, it->second);return it->second->second;}}

put 方法

    void put(int key, int value) {auto it = cacheMap_.find(key);if (it != cacheMap_.end()) {// Key already exists, update the value and move it to the frontit->second->second = value;cacheList_.splice(cacheList_.begin(), cacheList_, it->second);} else {if (cacheList_.size() == capacity_) {// Cache is full, remove the least recently used itemauto last = cacheList_.back();cacheMap_.erase(last.first);cacheList_.pop_back();}// Insert the new key-value pair at the frontcacheList_.emplace_front(key, value);cacheMap_[key] = cacheList_.begin();}}
http://www.shuangfujiaoyu.com/news/24117.html

相关文章:

  • 淮安做网站的有多少钱关键词排名批量查询
  • 北京市网站建设关键词搜索排名公司
  • 郑州经济技术开发区沈阳百度seo关键词排名优化软件
  • 在线logo设计商标免费百中搜优化软件
  • 做公司网站的费用计入什么科目seo臻系统
  • 网站开发哪家公司比较好武汉seo创造者
  • 旅游类网站建设受众分析百度软文
  • 网上购物哪个平台能买到正品保定seo外包服务商
  • 二手书交易网站开发毕业设计搜索引擎案例分析结论
  • 做名片制作网站有什么电商网络销售是做什么
  • 中英网站源码下载域名查询平台
  • 求手机网址长春网站优化指导
  • icp备案网站信息填写百度广告客服电话
  • 网站更换上海最近3天疫情情况
  • 万能小偷程序做网站最近一周新闻大事摘抄2022年
  • 修改wordpress后台登录地址福建seo推广方案
  • 网站建设总做总结中文搜索引擎
  • 大悟网站设计b2b有哪些电商平台
  • 网站正在建设中永久百度下载并安装到桌面
  • 北京网站建设备案代理seo排名点击软件
  • 上海知名的网站建设成都全网推广哪家专业
  • 网站日历代码seo排名赚下载
  • 网站域名使用代理口碑营销名词解释
  • 用wordpress搭建完整网站教程搜索引擎优化策略应该包括
  • 网站建设 杭州市萧山区免费网站排名优化软件
  • 网站seo的主要优化内容做个小程序需要花多少钱
  • 武汉企业高端网站建设搜索引擎关键词优化有哪些技巧
  • 应用商店app下载安装最新版软件seo优化排名价格
  • 源码网站git百度开户联系方式
  • 本地电脑如何做网站服务器优秀的营销案例