Problem
Note: This is a companion problem to the System Design problem: Design TinyURL.
TinyURL is a URL shortening service where you enter a URL such as https://leetcode.com/problems/design-tinyurl
and it returns a short URL such as http://tinyurl.com/4e9iAk
. Design a class to encode a URL and decode a tiny URL.
There is no restriction on how your encode/decode algorithm should work. You just need to ensure that a URL can be encoded to a tiny URL and the tiny URL can be decoded to the original URL.
Implement the Solution
class:
Solution()
Initializes the object of the system.String encode(String longUrl)
Returns a tiny URL for the givenlongUrl
.String decode(String shortUrl)
Returns the original long URL for the givenshortUrl
. It is guaranteed that the givenshortUrl
was encoded by the same object.
Examples
Example 1:
Input: url = "https://leetcode.com/problems/design-tinyurl"
Output: "https://leetcode.com/problems/design-tinyurl"
Explanation:
Solution obj = new Solution();
string tiny = obj.encode(url); // returns the encoded tiny url.
string ans = obj.decode(tiny); // returns the original url after deconding it.
Solution
Method 1 - Using Linked List
We can store the urls in the ArrayList
, and return the index at which it is stored.
Code
Java
public class Codec {
private final List<String> list = new ArrayList<>();
private static final String BASE_HOST = "http://tinyurl.com/";
// Encodes a URL to a shortened URL.
public String encode(String longUrl) {
list.add(longUrl);
return BASE_HOST.concat(String.valueOf(list.size()));
}
// Decodes a shortened URL to its original URL.
public String decode(String shortUrl) {
String[] parts = shortUrl.split(BASE_HOST);
String code = parts[1];
return list.get(Integer.parseInt(code) - 1);
}
}
Complexity
- ⏰ Time complexity:
O(1)
for both encoding and decoding. - 🧺 Space complexity:
O(n*l)
forn
urls with average lengthl
.
Method 2 - Using Hashmap
What if we want fixed length url, then this method can help. So, we do following
- Use
index
to map generated short url to long url - Use
revIndex
to map long url to short url (We can also use set here, but can help if we need to extend the problem) - We use do while loop to generate 6 digit random string, so that we enter the loop at-least once. We will just generate the short url or key. If it is already present in
index
, we will try again, till we find a new key which is not yet present inindex
. This avoids collisions. - Now, we are out loop, we save this generated
key
orshortUrl
toindex
and reverse mapping torevIndex
.
Code
Java
public class Codec {
Map<String, String> index = new HashMap<String, String>();
Map<String, String> revIndex = new HashMap<String, String>();
static String BASE_HOST = "http://tinyurl.com/";
// Encodes a URL to a shortened URL.
public String encode(String longUrl) {
if (revIndex.containsKey(longUrl)) return BASE_HOST + revIndex.get(longUrl);
String charSet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
String key = null;
do {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 6; i++) {
int r = (int) (Math.random() * charSet.length());
sb.append(charSet.charAt(r));
}
key = sb.toString();
} while (index.containsKey(key));
index.put(key, longUrl);
revIndex.put(longUrl, key);
return BASE_HOST + key;
}
// Decodes a shortened URL to its original URL.
public String decode(String shortUrl) {
return index.get(shortUrl.replace(BASE_HOST, ""));
}
}