Leetcode 535: Encode and Decode TinyURL
Design a URL shortening system where you can encode a long URL into a shortened URL and decode it back to the original URL. The system should guarantee that the original URL can always be retrieved using the shortened version.
Problem
Approach
Steps
Complexity
Input: The input consists of a valid long URL (string) that needs to be encoded into a shortened version. The input string will contain a valid URL of length between 1 and 10^4 characters.
Example: Input: longUrl = "https://example.com/article/12345"
Constraints:
• 1 <= longUrl.length <= 10^4
• The URL will be a valid string containing a valid URL.
Output: The output should return the encoded shortened URL, and when decoded, it should return the original URL.
Example: Output: "http://tinyurl.com/4e9iAk"
Constraints:
• The returned shortened URL should be valid and unique.
Goal: To design a system that can encode and decode URLs efficiently while ensuring uniqueness of the shortened URLs.
Steps:
• Use a random generation technique to create a unique short code for each long URL.
• Store the mapping between the original URL and the generated short URL in a data structure (e.g., a map).
• Use the short URL to look up and retrieve the corresponding original URL when decoding.
Goal: Ensure that the system handles valid URLs of up to 10^4 characters and produces unique shortened URLs.
Steps:
• The URL string is guaranteed to be a valid URL.
• The length of the URL string will be between 1 and 10^4 characters.
Assumptions:
• The input URL is valid and properly formatted.
• The solution does not need to handle invalid URLs or URLs that exceed the length limits.
• Input: Input: longUrl = "https://example.com/article/12345"
• Explanation: The long URL "https://example.com/article/12345" is encoded into a shorter version, such as "http://tinyurl.com/4e9iAk", which can be decoded back to the original URL.
Approach: To solve this problem, we can use a hashmap to store the original URL and its corresponding shortened URL. A random string generator will be used to ensure uniqueness for the shortened URLs.
Observations:
• A unique identifier (short code) needs to be generated for each long URL to ensure that each encoded URL maps to a unique decoded URL.
• Using a random character set will allow us to generate short and unique codes for each URL.
Steps:
• Create a random string generator that will produce a short code of fixed length (e.g., 6 characters).
• Use two hashmaps: one for mapping long URLs to short codes and the other for mapping short codes back to long URLs.
• When encoding, check if the long URL has already been encoded and use the existing code if available. Otherwise, generate a new code and store the mapping.
• When decoding, extract the code from the short URL and use the second hashmap to retrieve the original URL.
Empty Inputs:
• Ensure that empty URLs are handled properly. However, in this problem, the input will always be a valid URL.
Large Inputs:
• The system should handle long URLs up to 10^4 characters efficiently.
Special Values:
• Consider the case where multiple URLs map to the same shortened URL. This should not happen due to the uniqueness of the generated short codes.
Constraints:
• Make sure the system handles all edge cases, including valid URLs, large inputs, and properly handles the mappings.
class Solution {
const string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
random_device rd;
map<string, string> url_code, code_url;
public:
// Encodes a URL to a shortened URL.
string encode(string longUrl) {
string code;
if(!url_code.count(longUrl)) {
for(int i = 0; i < 6; i++)
code.push_back(charset[rd()%charset.size()]);
url_code.insert(pair<string, string>(longUrl, code));
code_url.insert(pair<string, string>(code, longUrl));
} else {
code = url_code[longUrl];
}
return "http://tinyurl.com/" + code;
}
// Decodes a shortened URL to its original URL.
string decode(string shortUrl) {
if(shortUrl.size() != 25 || !code_url.count(shortUrl.substr(19,6)))
return "";
return code_url[shortUrl.substr(19,6)];
}
};
// Your Solution object will be instantiated and called as such:
// Solution solution;
1 : Class Definition
class Solution {
Defines the `Solution` class which contains the encoding and decoding methods for URL shortening.
2 : Charset Definition
const string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Defines a constant string `charset` that contains all possible characters that can be used to generate the shortened URL.
3 : Random Device Initialization
random_device rd;
Declares a `random_device` object `rd` used for generating random numbers to ensure uniqueness in the encoded URL.
4 : Map Initialization
map<string, string> url_code, code_url;
Declares two maps: `url_code` which maps long URLs to shortened codes, and `code_url` which maps shortened codes back to long URLs.
5 : Access Control
public:
Declares the public access scope for the encoding and decoding methods.
6 : Encode Method Definition
string encode(string longUrl) {
Defines the `encode` method which takes a long URL as input and returns a shortened version of that URL.
7 : Variable Declaration
string code;
Declares a string variable `code` to store the randomly generated shortened code for the long URL.
8 : Check if URL Already Encoded
if(!url_code.count(longUrl)) {
Checks if the long URL is already encoded. If not, it proceeds to generate a new shortened URL.
9 : Random Code Generation
for(int i = 0; i < 6; i++)
Generates a random 6-character string by selecting random characters from the `charset` string.
10 : Push Back Character to Code
code.push_back(charset[rd()%charset.size()]);
Appends a random character from the `charset` string to the `code` string.
11 : Insert Long URL and Code
url_code.insert(pair<string, string>(longUrl, code));
Inserts the pair of the long URL and its corresponding shortened code into the `url_code` map.
12 : Insert Code and Long URL
code_url.insert(pair<string, string>(code, longUrl));
Inserts the pair of the shortened code and the long URL into the `code_url` map.
13 : Else Case for Existing URL
} else {
If the long URL is already encoded, the code simply retrieves the existing shortened code from the `url_code` map.
14 : Retrieve Existing Code
code = url_code[longUrl];
Retrieves the existing shortened code for the long URL from the `url_code` map.
15 : Return Encoded URL
return "http://tinyurl.com/" + code;
Returns the full shortened URL formed by concatenating the base URL with the generated shortened code.
16 : Decode Method Definition
string decode(string shortUrl) {
Defines the `decode` method which takes a shortened URL as input and returns the corresponding original long URL.
17 : Check URL Length and Validity
if(shortUrl.size() != 25 || !code_url.count(shortUrl.substr(19,6)))
Checks if the shortened URL has a valid length and if the map `code_url` contains the shortened code extracted from the URL.
18 : Return Empty String for Invalid URL
return "";
Returns an empty string if the shortened URL is invalid or if no matching code is found.
19 : Retrieve Original URL
return code_url[shortUrl.substr(19,6)];
Retrieves the original long URL from the `code_url` map using the shortened code extracted from the shortened URL.
Best Case: O(1)
Average Case: O(1)
Worst Case: O(1)
Description: The time complexity for both encoding and decoding is O(1), as hashmaps allow constant time retrieval and insertion.
Best Case: O(n)
Worst Case: O(n)
Description: The space complexity is O(n), where n is the number of unique URLs that have been encoded, as we need to store the mappings in hashmaps.
LeetCode Solutions Library / DSA Sheets / Course Catalog |
---|
comments powered by Disqus