leetcode 1797. 设计一个验证系统

139 阅读2分钟

1. 题目与解析

需要设计一个包含验证码的验证系统。每一次验证中,用户会收到一个新的验证码,这个验证码在 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 操作),过期事件 优先于 其他操作。

输入:

["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]

按照题意,用一个哈希表timeMap保存验证码和过期时间。调用 generate()时,将验证码-过期时间对直接插入timeMap。调用 renew() 时,如果验证码存在并且未过期,则更新过期时间。调用 countUnexpiredTokens() 时,遍历整个 timeMap,统计未过期的验证码的数量。

解体的过程中有两个需要注意的小细节

  • 需要注意,调用 renew() 时,需要进行是否过期的判断,如果过期了,就将其删除,不进行更新操作;
  • 另一个需要注意的点是,过期时间的判断过程是需要取等号的,距离来说,如果验证码在时间t过期,那么当判断时间正好为t时,验证码就已经过期了。

2. 题解

class AuthenticationManager {
    Map<String, Integer> timeMap;
    int timeToLive;

    public AuthenticationManager(int timeToLive) {
        timeMap = new HashMap<>();
        this.timeToLive = timeToLive;
    }
    
    public void generate(String tokenId, int currentTime) {
        timeMap.put(tokenId, currentTime+timeToLive);
    }
    
    public void renew(String tokenId, int currentTime) {
        if (!timeMap.containsKey(tokenId)) {
            return;
        }
        if (timeMap.get(tokenId) <= currentTime) {
            timeMap.remove(tokenId);
            return;
        }
        timeMap.put(tokenId, currentTime+timeToLive);
    }
    
    public int countUnexpiredTokens(int currentTime) {
        int ans = 0;
        for (Map.Entry<String, Integer> e: timeMap.entrySet()) {
            if (currentTime < e.getValue()) {
                ans++;
            }
        }
        return ans;
    }
}