Design Authentication Manager - Complete Solution Guide
Design Authentication Manager is LeetCode problem 1797, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
There is an authentication system that works with authentication tokens. For each session, the user will receive a new authentication token that will expire timeToLive seconds after the currentTime . If the token is renewed, the expiry time will be extended to expire timeToLive seconds after the (potentially different) currentTime . Implement the AuthenticationManager class: AuthenticationManager(int timeToLive) constructs the AuthenticationManager and sets the timeToLive . generate(string token
Detailed Explanation
The problem asks us to design an authentication system that manages user authentication tokens. Each token has a `tokenId` and an expiration time, which is determined by the `timeToLive` and the `currentTime` when the token is generated or renewed. The system needs to support generating new tokens, renewing existing unexpired tokens, and counting the number of unexpired tokens at a given time. The `currentTime` is strictly increasing across all operations, and it's important to consider that if a token expires at time t, and another action happens at time t, the expiration takes precedence. This implies checking the validity of a token *before* performing any operation on it.
Solution Approach
The provided solution uses a hash table (`tokens`) to store the `tokenId` and its corresponding expiration time. The `generate` function simply adds a new entry to the hash table. The `renew` function checks if the token exists and if its expiry time is greater than the current time; if so, it updates the expiry time. The `countUnexpiredTokens` function iterates through the hash table, checks for expired tokens, removes them, and then returns the number of remaining tokens.
Step-by-Step Algorithm
- Step 1: Initialize the AuthenticationManager with the given `timeToLive` and an empty hash table `tokens` to store token information.
- Step 2: Implement the `generate` function: Store a new token in the `tokens` hash table, with the `tokenId` as the key and the `currentTime + timeToLive` as the value (expiration time).
- Step 3: Implement the `renew` function: Check if the `tokenId` exists in the `tokens` hash table AND if the token's expiration time is greater than the `currentTime`. If both conditions are true, update the token's expiration time to `currentTime + timeToLive`.
- Step 4: Implement the `countUnexpiredTokens` function: Iterate through the `tokens` hash table. For each token, check if its expiration time is less than or equal to the `currentTime`. If it is, add the `tokenId` to a list of tokens to be removed. After iterating, remove all expired tokens from the `tokens` hash table.
- Step 5: Finally, return the number of tokens remaining in the `tokens` hash table. This represents the number of unexpired tokens.
Key Insights
- Key Insight 1: Using a hash table (dictionary/unordered_map) to store the tokens allows efficient lookups, insertions, and deletions based on the `tokenId`.
- Key Insight 2: The 'currentTime' is strictly increasing, simplifying the problem since we don't need to sort or handle out-of-order events. We only need to check if a token's expiry time is greater than the current time.
- Key Insight 3: When counting unexpired tokens, it's necessary to remove expired tokens from the data structure to maintain an accurate count and prevent future operations from acting on them. This removal needs to happen *before* returning the count.
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(n)
Topics
This problem involves: Hash Table, Linked List, Design, Doubly-Linked List.
Companies
Asked at: Confluent, Docusign, Genpact, X.