【LeetCode每日一题】【2023/2/9】1797. 设计一个验证系统
创始人
2024-05-23 16:29:13
0

文章目录

  • 1797. 设计一个验证系统
    • 方法1:哈希表
      • 代码总体


1797. 设计一个验证系统

LeetCode: 1797. 设计一个验证系统

中等\color{#FFB800}{中等}中等

你需要设计一个包含验证码的验证系统。每一次验证中,用户会收到一个新的验证码,这个验证码在 currentTime 时刻之后 timeToLive 秒过期。如果验证码被更新了,那么它会在 currentTime (可能与之前的 currentTime 不同)时刻延长 timeToLive 秒。

请你实现 AuthenticationManager 类:

  • AuthenticationManager(int timeToLive) 构造 AuthenticationManager 并设置 timeToLive 参数。
  • generate(string tokenId, int currentTime) 给定 tokenId ,在当前时间 currentTime 生成一个新的验证码。
  • renew(string tokenId, int currentTime) 将给定 tokenId未过期 的验证码在 currentTime 时刻更新。如果给定 tokenId 对应的验证码不存在或已过期,请你忽略该操作,不会有任何更新操作发生。
  • countUnexpiredTokens(int currentTime) 请返回在给定 currentTime 时刻,未过期 的验证码数目。

如果一个验证码在时刻 t 过期,且另一个操作恰好在时刻 t 发生(renew 或者 countUnexpiredTokens 操作),过期事件 优先于 其他操作。

示例 1:

在这里插入图片描述

输入:
["AuthenticationManager", "renew", "generate", "countUnexpiredTokens", "generate", "renew", "renew", "countUnexpiredTokens"]
[[5], ["aaa", 1], ["aaa", 2], [6], ["bbb", 7], ["aaa", 8], ["bbb", 10], [15]]
输出:
[null, null, null, 1, null, null, null, 0]解释:
AuthenticationManager authenticationManager = new AuthenticationManager(5); // 构造 AuthenticationManager ,设置 timeToLive = 5 秒。
authenticationManager.renew("aaa", 1); // 时刻 1 时,没有验证码的 tokenId 为 "aaa" ,没有验证码被更新。
authenticationManager.generate("aaa", 2); // 时刻 2 时,生成一个 tokenId 为 "aaa" 的新验证码。
authenticationManager.countUnexpiredTokens(6); // 时刻 6 时,只有 tokenId 为 "aaa" 的验证码未过期,所以返回 1 。
authenticationManager.generate("bbb", 7); // 时刻 7 时,生成一个 tokenId 为 "bbb" 的新验证码。
authenticationManager.renew("aaa", 8); // tokenId 为 "aaa" 的验证码在时刻 7 过期,且 8 >= 7 ,所以时刻 8 的renew 操作被忽略,没有验证码被更新。
authenticationManager.renew("bbb", 10); // tokenId 为 "bbb" 的验证码在时刻 10 没有过期,所以 renew 操作会执行,该 token 将在时刻 15 过期。
authenticationManager.countUnexpiredTokens(15); // tokenId 为 "bbb" 的验证码在时刻 15 过期,tokenId 为 "aaa" 的验证码在时刻 7 过期,所有验证码均已过期,所以返回 0 。

提示:

  • 1 <= timeToLive <= 10^8
  • 1 <= currentTime <= 10^8
  • 1 <= tokenId.length <= 5
  • tokenId 只包含小写英文字母。
  • 所有 generate 函数的调用都会包含独一无二的 tokenId 值。
  • 所有函数调用中,currentTime 的值 严格递增
  • 所有函数的调用次数总共不超过 2000 次。

方法1:哈希表

使用哈希表来存放验证码及其过期时间。哈希表的键为验证码字符串,值为对应的过期时间。

构造函数将 timeToLive 记录下来:

class AuthenticationManager
{
public:explicit AuthenticationManager(const int timeToLive): ttl{timeToLive} { }private:const int ttl;
};

函数 generate() 将传入的 tokenId 记录下来,并将 currentTime 加上 ttl 作为该验证码的 过期时间 记录下来:

void generate(string tokenId, const int currentTime)
{hashtable.emplace(std::move(tokenId), currentTime + ttl);
}

函数 renew() 实现验证码的更新。按题意,若哈希表中没有找到该验证码,则不做任何操作;若该验证码的过期时间 小于等于 当前时间 currentTime ,则删除,否则更新为 currentTime + ttl ,即在当前时间下 延后 ttl 个时间。

void renew(const string& tokenId, const int currentTime)
{if (const auto it = hashtable.find(tokenId);it != hashtable.end()){if (it->second > currentTime)it->second = currentTime + ttl;elsehashtable.erase(it);}
}

函数 countUnexpiredTokens 在调用函数 clearExpiredTokens 清除 过期 验证码后,返回哈希表中的元素个数,即为所求的当前 未过期 的验证码。

int countUnexpiredTokens(const int currentTime)
{clearExpiredTokens(currentTime);return static_cast(hashtable.size());
}

函数 clearExpiredTokens 遍历哈希表,并逐个删除 过期的 验证码:

void clearExpiredTokens(const int currentTime)
{for (auto it = hashtable.begin(); it != hashtable.end();){if (const auto& [_, expireTime] = *it;expireTime <= currentTime)it = hashtable.erase(it);else++it;}
}

代码总体

#include 
#include 
using namespace std;class AuthenticationManager
{
public:explicit AuthenticationManager(const int timeToLive): ttl{timeToLive} { }void generate(string tokenId, const int currentTime){hashtable.emplace(std::move(tokenId), currentTime + ttl);}void renew(const string& tokenId, const int currentTime){if (const auto it = hashtable.find(tokenId);it != hashtable.end()){if (it->second > currentTime)it->second = currentTime + ttl;elsehashtable.erase(it);}}int countUnexpiredTokens(const int currentTime){clearExpiredTokens(currentTime);return static_cast(hashtable.size());}private:void clearExpiredTokens(const int currentTime){for (auto it = hashtable.begin(); it != hashtable.end();){if (const auto& [_, expireTime] = *it;expireTime <= currentTime)it = hashtable.erase(it);else++it;}}private:const int ttl;unordered_map hashtable;
};

复杂度分析:

  • 时间复杂度:

    • 构造函数:O(1)O(1)O(1)
    • generate():O(1)O(1)O(1),哈希表的插入操作即为 O(1)O(1)O(1) 的时间复杂度。
    • renew():O(1)O(1)O(1),哈希表的查找、删除操作均为 O(1)O(1)O(1) 的时间复杂度。
    • countUnexpiredTokens():O(n)O(n)O(n),其中 nnn 为哈希表中的验证码元素个数,或者说就是函数 generate() 的调用次数。
  • 空间复杂度:O(n)O(n)O(n)。其中 nnn 为函数 generate() 的调用次数,主要为哈希表的开销。

参考结果

Accepted
90/90 cases passed (76 ms)
Your runtime beats 65.89 % of cpp submissions
Your memory usage beats 89.25 % of cpp submissions (29.3 MB)

若每次调用 generate()renew() 时都打算清理 过期的 验证码,那么由于函数 clearExpiredTokens() 的时间复杂度为 O(n)O(n)O(n) ,函数 generate()renew() 的时间复杂度也会继而变为 O(n)O(n)O(n) 。

参考结果如下:

Accepted
90/90 cases passed (92 ms)
Your runtime beats 34.58 % of cpp submissions
Your memory usage beats 93.46 % of cpp submissions (29.3 MB) 

相关内容

热门资讯

四年级描写小公鸡的作文【精简... 四年级描写小公鸡的作文 篇一小公鸡的生活小公鸡是一只活泼可爱的小动物,它们有着鲜艳的羽毛和红红的冠子...
四年级作文假如我来当老师【经... 四年级作文假如我来当老师 篇一如果我来当老师,我会尽力做到最好。作为一个四年级的学生,我对自己的能力...
六年级上册语文第三单元作文(... 六年级上册语文第三单元作文 篇一主题:我的家乡我的家乡位于一个小城市,虽然不大,但是我对它有着深深的...
期末考试小学生六年级作文(经... 期末考试小学生六年级作文 篇一我的成长随着时间的推移,我已经到了小学六年级了。在这个学期即将结束之际...
关爱的六年级作文400字 【实用】关爱的六年级作文400字合集9篇  无论是在学校还是在社会中,大家都经常看到作文的身影吧,作...
六年级作文(最新6篇) 六年级作文 篇一:我的暑假生活这个暑假,我过得非常充实和有意义。我参加了许多有趣的活动,也学到了很多...
春天的校园六年级作文400字... 春天的校园六年级作文400字 篇一:春风吹拂的校园春天是一个美丽的季节,也是一个充满希望和活力的季节...
六年级下册让真情自然流露作文... 六年级下册让真情自然流露作文 篇一真情的力量在我们的生活中,真情是一种宝贵的力量。它可以让我们更加真...
走进新学期六年级作文(优质3... 走进新学期六年级作文 篇一新学期开始了,我升入了六年级。对于这个新的开始,我既充满期待又有些紧张。首...
黑暗中的光明六年级作文【经典... 黑暗中的光明六年级作文 篇一:勇敢面对黑暗黑暗,对于很多人来说,是一种恐惧的存在。在黑暗中,我们看不...
青春如彩虹般绚丽作文600字... 青春如彩虹般绚丽作文600字六年级 篇一青春是一段美丽而绚烂的时光,就像彩虹一样绚丽多彩。在这段青春...
夜游珠江六年级作文550字【... 夜游珠江六年级作文550字 篇一夜游珠江夜晚,珠江两岸的灯光闪烁,江面波光粼粼,我和爸爸妈妈一起来到...
小升初满分作文:奶奶的爱【推... 小升初满分作文:奶奶的爱 篇一奶奶是我最亲近的人,她的爱无处不在。无论是在家里还是在学校,奶奶总是给...
追梦人600字作文 追梦人600字作文···· 追梦人···· 桥林小学 六(3)班 李斌每个人都有梦想,人生有了梦想就...
感恩朋友六年级作文【最新3篇... 感恩朋友六年级作文 篇一感恩朋友朋友,是我们成长道路上最为珍贵的财富。她们和我一起度过了美好的六年级...
一到六年级的作文下雨【实用6... 一到六年级的作文下雨 篇一雨天的乐趣下雨了,这是多少孩子最喜欢的天气啊!尤其是在一到六年级的小学生们...
哥哥真厉害作文1000字【优... 哥哥真厉害作文1000字 篇一哥哥真厉害我有一个哥哥,他是我心目中最厉害的人。他不仅聪明、勤奋,还有...
六年级上册第二单元作文(优秀... 六年级上册第二单元作文 篇一我的梦想我是一个六年级的学生,我的名字叫小明。每个人都有自己的梦想,而我...
小学六年级暑假作文400字(... 小学六年级暑假作文400字 篇一:我的暑假生活暑假来临了,我迫不及待地迎接了属于我的自由时光。暑假里...
我是一场秋雨小学六年级作文(... 我是一场秋雨小学六年级作文 篇一:秋雨的魅力秋天是一个美丽的季节,它给大地带来了一场场降雨,也给我们...