GuilinDev

Lc1797

05 August 2008

1797. Design Authentication Manager

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

哈希表模拟

思路其实是在模拟缓存中的 token 操作。 首先创建一个哈希表,哈希表中的:

key : tokenId value : 生成时间,也就是调用 generate 或者 renew 时带进来的 currentTime。 更具体的就看下面注释吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class AuthenticationManager {
    private int timeToLive;
    private Map<String, Integer> tokens;

    public AuthenticationManager(int timeToLive) {
        tokens = new HashMap<>();
        this.timeToLive = timeToLive;
    }

    /**
     * 根据题意,不需要考虑是否之前已经存在了,只需要把 tokenId-currentTime 更新/添加到哈希表中就好
     */
    public void generate(String tokenId, int currentTime) {
        tokens.put(tokenId, currentTime);
    }

    public void renew(String tokenId, int currentTime) {
        // 首先看看缓存(哈希表)中里面有没有对应的 tokenId,如果没有就什么都不用做了
        if (tokens.containsKey(tokenId)) {
            // 如果有的话,先记录下来它的上次生成时间
            int time = tokens.get(tokenId);
            // currentTime - time 就是上次生成时间和当前时间的差值
            // 如果差值严格小于生存时间 timeToLive ,那么就可以更新了,否则什么都不做
            if (currentTime - time < timeToLive) tokens.put(tokenId, currentTime);
        }
    }

    public int countUnexpiredTokens(int currentTime) {
        int result = 0;
        // 对缓存(哈希表)中的每一个对象进行遍历,检查他们的生成时间和当前时间的差值是否满足要求
        for (Map.Entry<String, Integer> entry : tokens.entrySet()) {
            if (currentTime - entry.getValue() < timeToLive) ++result;
        }
        return result;
    }
}

/**
 * Your AuthenticationManager object will be instantiated and called as such:
 * AuthenticationManager obj = new AuthenticationManager(timeToLive);
 * obj.generate(tokenId,currentTime);
 * obj.renew(tokenId,currentTime);
 * int param_3 = obj.countUnexpiredTokens(currentTime);
 */