LeetCode 535: Encode and Decode TinyURL Solution in Python – A Step-by-Step Guide

Imagine you’re crafting a tool to shrink massive URLs—like "https://www.example.com/very/long/path"—into snappy short links like "tinyurl.com/xyz123," and then magically turning them back into the original when needed. That’s the clever challenge of LeetCode 535: Encode and Decode TinyURL, a medium-level problem that’s a fantastic way to practice system design in Python. We’ll explore two solutions: the Best Solution, a hash map with random key generation that’s simple and efficient, and an Alternative Solution, a base62 encoding with counter approach that’s predictable but slightly more complex. With detailed examples, clear code, and a friendly tone—especially for the random key method—this guide will help you master URL shortening, whether you’re new to coding or leveling up. Let’s shrink those links and start encoding!

What Is LeetCode 535: Encode and Decode TinyURL?

Section link icon

In LeetCode 535: Encode and Decode TinyURL, you’re tasked with designing a Codec class with two methods: encode(longUrl) to convert a long URL into a short one, and decode(shortUrl) to retrieve the original URL. The short URL must be unique, shorter than the original, and correctly map back to the long URL. For example, encoding "https://leetcode.com/problems/design-tinyurl" might yield "tinyurl.com/abc123," and decoding that returns the original. This problem tests hash map usage and string manipulation, related to LeetCode 146: LRU Cache for key-value storage.

Problem Statement

  • Input:
    • encode(longUrl): String—original URL.
    • decode(shortUrl): String—shortened URL.
  • Output:
    • encode: String—short URL.
    • decode: String—original URL.
  • Rules: Short URL must be unique, shorter than original; decode must return exact input.

Constraints

  • 1 <= longUrl.length <= 10⁴
  • URLs are valid and contain lowercase letters, digits, and special characters.
  • At most 10⁴ calls to encode and decode.

Examples

  • Input:
  • ``` ["encode","decode"] [["https://leetcode.com/problems/design-tinyurl"],["tinyurl.com/abc123"]] ```
    • Output:
    • ``` ["tinyurl.com/abc123","https://leetcode.com/problems/design-tinyurl"] ```
  • Input:
  • ``` ["encode","encode","decode"] [["https://www.example.com"],["https://python.org"],["tinyurl.com/xyz789"]] ```
    • Output:
    • ``` ["tinyurl.com/xyz789","tinyurl.com/pqr456","https://www.example.com"] ```

Understanding the Problem: Shortening URLs

Section link icon

To solve LeetCode 535: Encode and Decode TinyURL in Python, we need a class with encode and decode methods that map long URLs to unique short URLs and back. A naive approach might store the full URL as a key, but we need short, unique codes. With up to 10⁴ calls, efficiency and simplicity are key. We’ll explore:

  • Best Solution (Hash Map with Random Key Generation): O(1) average encode/decode, O(n) space (n = URLs)—simple and fast.
  • Alternative Solution (Base62 Encoding with Counter): O(1) encode/decode, O(n) space—predictable but requires base conversion.

Let’s dive into the random key solution with a friendly breakdown!

Best Solution: Hash Map with Random Key Generation

Section link icon

Why Random Key Generation Wins

The hash map with random key generation is the best for LeetCode 535 because it’s straightforward, generates short unique codes in O(1) average time per operation using a random 6-character key, and uses O(n) space with a hash map for storage. It’s like rolling a dice to pick a short code and checking if it’s taken!

How It Works

Think of this as a URL lottery:

  • Step 1: Setup:
    • Use a hash map to store short-to-long URL mappings.
    • Define an alphabet (e.g., a-z, A-Z, 0-9) for random keys.
  • Step 2: Encode:
    • Generate a random 6-character key (e.g., "xyz123").
    • If key exists, retry until unique.
    • Form short URL (e.g., "tinyurl.com/xyz123"), store in map.
  • Step 3: Decode:
    • Extract key from short URL, look up in map.
  • Why It Works:
    • 6 chars with 62 options ≈ 56 million possibilities, low collision chance for 10⁴ URLs.
    • Simple and fast with hash map lookups.

It’s like a TinyURL dice roller!

Step-by-Step Example

Example: Encoding "https://leetcode.com/problems/design-tinyurl"

  • Init: url_map = {}, chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".
  • Step 1: encode("https://leetcode.com/problems/design-tinyurl"):
    • Random key = "abc123".
    • Short URL = "tinyurl.com/abc123".
    • url_map["abc123"] = "https://leetcode.com/problems/design-tinyurl".
  • Step 2: encode("https://www.example.com"):
    • Random key = "xyz789" (assume "abc123" not reused).
    • Short URL = "tinyurl.com/xyz789".
    • url_map["xyz789"] = "https://www.example.com".
  • Step 3: decode("tinyurl.com/abc123"):
    • Extract "abc123", url_map["abc123"] = "https://leetcode.com/problems/design-tinyurl".
  • Result: "https://leetcode.com/problems/design-tinyurl".

Code with Detailed Line-by-Line Explanation

Here’s the Python code, explained for beginners:

import random

class Codec:
    def __init__(self):
        # Step 1: Initialize hash map and alphabet
        self.url_map = {}
        self.chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        self.prefix = "tinyurl.com/"

    def encode(self, longUrl: str) -> str:
        # Step 2: Generate unique random key
        while True:
            key = ''.join(random.choice(self.chars) for _ in range(6))
            short_url = self.prefix + key
            if key not in self.url_map:
                self.url_map[key] = longUrl
                return short_url

    def decode(self, shortUrl: str) -> str:
        # Step 3: Extract key and lookup
        key = shortUrl[len(self.prefix):]
        return self.url_map.get(key, "")
  • Lines 6-8: Constructor: Hash map, 62-char alphabet, prefix.
  • Lines 11-16: encode:
    • Generate 6-char key, ensure uniqueness, store mapping.
  • Lines 19-21: decode:
    • Extract key, return long URL.
  • Time Complexity: O(1) average—rare collisions.
  • Space Complexity: O(n)—hash map size.

It’s like a TinyURL randomizer!

Alternative Solution: Base62 Encoding with Counter

Section link icon

Why an Alternative Approach?

The base62 encoding with counter solution uses a counter to generate deterministic short codes, converting them to base62 (a-z, A-Z, 0-9), ensuring uniqueness without retries. It’s O(1) time per operation (base conversion is small) and O(n) space—predictable but requires base62 logic. Great for deterministic fans!

How It Works

Picture this as a URL code counter:

  • Step 1: Setup hash map, counter, base62 alphabet.
  • Step 2: encode:
    • Increment counter, convert to base62 (e.g., 1 → "a").
    • Form short URL, store in map.
  • Step 3: decode:
    • Extract code, lookup in map.

It’s like a TinyURL counter!

Step-by-Step Example

Example: Encoding "https://www.example.com"

  • Init: counter = 0, map = {}, base62 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".
  • Step 1: encode:
    • counter = 1, base62: 1 → "b".
    • Short URL = "tinyurl.com/b".
    • map["b"] = "https://www.example.com".
  • Step 2: decode("tinyurl.com/b"):
    • Key = "b", map["b"] = "https://www.example.com".
  • Result: "https://www.example.com".

Code for Base62 Approach

class Codec:
    def __init__(self):
        self.url_map = {}
        self.counter = 0
        self.base62 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        self.prefix = "tinyurl.com/"

    def encode(self, longUrl: str) -> str:
        self.counter += 1
        num = self.counter
        code = ""
        while num > 0:
            code = self.base62[num % 62] + code
            num //= 62
        short_url = self.prefix + code
        self.url_map[code] = longUrl
        return short_url

    def decode(self, shortUrl: str) -> str:
        code = shortUrl[len(self.prefix):]
        return self.url_map.get(code, "")
  • Time Complexity: O(1)—base62 conversion is small.
  • Space Complexity: O(n)—hash map.

It’s a base62 URL encoder!

Comparing the Two Solutions

Section link icon
  • Random Key (Best):
    • Pros: O(1) avg, O(n), simple.
    • Cons: Collision risk (low).
  • Base62 (Alternative):
    • Pros: O(1), O(n), deterministic.
    • Cons: Base62 logic.

Random key wins for simplicity!

Additional Examples and Edge Cases

Section link icon
  • "https://a.com": Shortens uniquely.
  • Duplicate URLs: Same short URL (allowed).
  • Long URLs: Consistent shortening.

Random key handles them all!

Complexity Recap

Section link icon
  • Random Key: Init O(1), Encode/Decode O(1) avg, Space O(n).
  • Base62: Init O(1), Encode/Decode O(1), Space O(n).

Random key’s the simplicity champ!

Key Takeaways

Section link icon
  • Random Key: Easy wins—learn at Python Basics!
  • Base62: Predictable power.
  • Design: URLs are fun.
  • Python: Random or counters, your pick!