Encode and Decode TinyURL

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 the encode and decode methods for the TinyURL service. 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.

public class Codec {
    
    private Map<String,String> short2long;
    private Map<String,String> long2short;
    private String dic;
    
    public Codec(){
        short2long = new HashMap<>();
        long2short = new HashMap<>();
        dic = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        short2long.clear();
        long2short.clear();
    }
    // Encodes a URL to a shortened URL.
    public String encode(String longUrl) {
        if(long2short.containsKey(longUrl)){
            return "http://tinyurl.com/"+long2short.get(longUrl);
        }
        
        int index = 0;
        Random r = new Random();
        String randomStr = "";
        for(int i =0; i < 6;i++){
            randomStr += dic.charAt(r.nextInt(62));
        }
        
        while(short2long.containsKey(randomStr)){

            int rdNum = r.nextInt(62);
            randomStr = randomStr.substring(0,index) + dic.charAt(rdNum) + randomStr.substring(index+1);
            //random string length 6
            index = (index + 1) % 5;
        }
        
        long2short.put(longUrl,randomStr);
        short2long.put(randomStr,longUrl);
        
        return "http://tinyurl.com/"+randomStr;
    }

    // Decodes a shortened URL to its original URL.
    public String decode(String shortUrl) {
        String str = shortUrl.substring(shortUrl.lastIndexOf("/")+1);
        
        return short2long.containsKey(str)  ? short2long.get(str) : shortUrl;
    }
}

// Your Codec object will be instantiated and called as such:
// Codec codec = new Codec();
// codec.decode(codec.encode(url));

  • The number of URLs that can be encoded is quite large in this case, nearly of the order (10+26*2)^6(10+26∗2)6.

  • The length of the encoded URLs is fixed to 6 units, which is a significant reduction for very large URLs.

  • The performance of this scheme is quite good, due to a very less probability of repeated same codes generated.

  • We can increase the number of encodings possible as well, by increasing the length of the encoded strings. Thus, there exists a tradeoff between the length of the code and the number of encodings possible.

  • Predicting the encoding isn't possible in this scheme since random numbers are used.


public class Codec {
    String alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    HashMap<String, String> map = new HashMap<>();
    Random rand = new Random();
    String key = getRand();

    public String getRand() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            sb.append(alphabet.charAt(rand.nextInt(62)));
        }
        return sb.toString();
    }

    public String encode(String longUrl) {
        while (map.containsKey(key)) {
            key = getRand();
        }
        map.put(key, longUrl);
        return "http://tinyurl.com/" + key;
    }

    public String decode(String shortUrl) {
        return map.get(shortUrl.replace("http://tinyurl.com/", ""));
    }
}

Last updated