LeetCode 524: Longest Word in Dictionary through Deleting Solution in Python – A Step-by-Step Guide

Imagine you’re handed a string like “abpcplea” and a dictionary of words—like “ale,” “apple,” “monkey,” “plea”—and your task is to find the longest word you can make by deleting letters from the string, keeping the order intact. That’s the engaging challenge of LeetCode 524: Longest Word in Dictionary through Deleting, a medium-level problem that’s a fantastic way to practice string manipulation in Python. We’ll explore two solutions: the Best Solution, a sorting with subsequence check that’s efficient and clever, and an Alternative Solution, a brute-force subsequence generation approach that’s thorough but slower. With detailed examples, clear code, and a friendly tone—especially for the subsequence check—this guide will help you find that longest word, whether you’re new to coding or leveling up. Let’s dive into the strings and start deleting!

What Is LeetCode 524: Longest Word in Dictionary through Deleting?

Section link icon

In LeetCode 524: Longest Word in Dictionary through Deleting, you’re given a string s and a list of strings dictionary, and your task is to find the longest word in dictionary that can be formed by deleting some (or no) characters from s while preserving the relative order of the remaining characters. If multiple words tie for the longest, return the lexicographically smallest. For example, with s = "abpcplea" and dictionary = ["ale", "apple", "monkey", "plea"], “apple” (length 5) is the longest valid word. This problem builds on LeetCode 392: Is Subsequence.

Problem Statement

  • Input:
    • s (str): Source string.
    • dictionary (List[str]): List of candidate words.
  • Output: String—longest word formable by deleting from s, or "" if none.
  • Rules: Subsequence must match word; longest wins; if tied, lexicographically smallest.

Constraints

  • 1 <= s.length <= 1000
  • 1 <= dictionary.length <= 1000
  • 1 <= dictionary[i].length <= 1000
  • s and dictionary[i] contain only lowercase English letters.

Examples

  • Input: s = "abpcplea", dictionary = ["ale","apple","monkey","plea"]
    • Output: "apple"
    • “apple” (length 5) is longest; “plea” (4) is shorter.
  • Input: s = "abpcplea", dictionary = ["a","b","c"]
    • Output: "a"
    • All length 1; “a” is lexicographically smallest.
  • Input: s = "abc", dictionary = ["def"]
    • Output: ""
    • No word formable.

Understanding the Problem: Crafting Words by Deletion

Section link icon

To solve LeetCode 524: Longest Word in Dictionary through Deleting in Python, we need to find the longest word in dictionary that’s a subsequence of s—meaning we can delete characters from s to match it while keeping the order. A naive approach might generate all subsequences of s, but with lengths up to 1000, that’s impractical. We’ll explore:

  • Best Solution (Sorting with Subsequence Check): O(n m k) time, O(1) space (n = dictionary length, m = avg word length, k = s length)—efficient and practical.
  • Alternative Solution (Brute-Force Subsequence Generation): O(2ᵏ n m) time, O(2ᵏ) space—exhaustive but slow.

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

Best Solution: Sorting with Subsequence Check

Section link icon

Why Sorting with Subsequence Check Wins

The sorting with subsequence check is the best for LeetCode 524 because it optimizes the search by sorting the dictionary by length and lexicographical order, then efficiently checks each word as a subsequence of s using a two-pointer method. It runs in O(n * m * k) time and O(1) space (excluding input), making it scalable. It’s like organizing your word list and quickly ticking off matches!

How It Works

Think of this as a word-matching game:

  • Step 1: Sort Dictionary:
    • Sort dictionary by decreasing length, then lexicographically within same lengths.
  • Step 2: Subsequence Check:
    • For each word, check if it’s a subsequence of s using two pointers.
  • Step 3: Find Longest:
    • Return first valid word (longest, lexicographically smallest due to sort).
  • Why It Works:
    • Sorting ensures longest valid word is checked first.
    • Subsequence check is linear per word.

It’s like a word-deletion detective!

Step-by-Step Example

Example: s = "abpcplea", dictionary = ["ale", "apple", "monkey", "plea"]

  • Step 1: Sort dictionary:
    • ["monkey", "apple", "plea", "ale"] (lengths: 6, 5, 4, 3).
  • Step 2: Check each:
    • “monkey”:
      • s: abpcplea, i=0, j=0.
      • m→a (no), b→o (no), …, fails.
    • “apple”:
      • s: abpcplea, i=0, j=0.
      • a→a, b→p, p→p, c→l, l→e, e→end, matches.
      • Length 5, return “apple”.
  • Result: "apple".

Example: s = "abpcplea", dictionary = ["a", "b", "c"]

  • Step 1: Sort: ["a", "b", "c"] (all 1, alphabetical).
  • Step 2: “a” matches (s[0]), return “a”.
  • Result: "a".

Code with Detailed Line-by-Line Explanation

Here’s the Python code, explained for beginners:

class Solution:
    def findLongestWord(self, s: str, dictionary: List[str]) -> str:
        # Step 1: Sort dictionary by length (desc) and lexicographically
        dictionary.sort(key=lambda x: (-len(x), x))

        # Step 2: Subsequence check helper
        def is_subsequence(word, s):
            i = 0
            for char in s:
                if i < len(word) and char == word[i]:
                    i += 1
            return i == len(word)

        # Step 3: Check each word
        for word in dictionary:
            if is_subsequence(word, s):
                return word

        # Step 4: No match found
        return ""
  • Line 4: Sort by decreasing length, then alphabetically.
  • Lines 7-12: is_subsequence:
    • Two-pointer: Match word in s, return True if all match.
  • Lines 15-17: Check each word; return first match (longest, smallest).
  • Line 20: Default to empty string if no match.
  • Time Complexity: O(n m k)—n words, m avg word length, k = s length.
  • Space Complexity: O(1)—no extra space beyond input.

It’s like a word-matching maestro!

Alternative Solution: Brute-Force Subsequence Generation

Section link icon

Why an Alternative Approach?

The brute-force subsequence generation solution generates all subsequences of s and checks them against the dictionary to find the longest match. It’s O(2ᵏ * n * m) time and O(2ᵏ) space—exhaustive but impractical for large strings, though it shows the full process. Great for learning subsequences!

How It Works

Picture this as a subsequence scavenger hunt:

  • Step 1: Generate all subsequences of s.
  • Step 2: Check each against dictionary, track longest match.
  • Step 3: Return longest, lexicographically smallest match.

It’s like a string treasure dig!

Step-by-Step Example

Example: s = "ab", dictionary = ["a", "b"]

  • Step 1: Subsequences of “ab”: “”, “a”, “b”, “ab”.
  • Step 2: Check dictionary:
    • “a” matches, length 1.
    • “b” matches, length 1.
  • Step 3: Longest = 1, “a” is smallest.
  • Result: "a".

Code for Brute-Force Approach

class Solution:
    def findLongestWord(self, s: str, dictionary: List[str]) -> str:
        # Step 1: Generate all subsequences
        def get_subsequences(s):
            subs = set()
            n = len(s)
            for mask in range(1 << n):
                sub = ""
                for i in range(n):
                    if mask & (1 << i):
                        sub += s[i]
                subs.add(sub)
            return subs

        # Step 2: Get subsequences and dictionary set
        subs = get_subsequences(s)
        dict_set = set(dictionary)

        # Step 3: Find longest match
        max_len = -1
        result = ""
        for sub in subs:
            if sub in dict_set:
                if len(sub) > max_len or (len(sub) == max_len and sub < result):
                    max_len = len(sub)
                    result = sub

        return result if max_len > 0 else ""
  • Lines 4-12: Generate subsequences with bitmask.
  • Lines 15-16: Get all subsequences and dictionary set.
  • Lines 19-24: Find longest match, prefer lexicographically smaller.
  • Time Complexity: O(2ᵏ n m)—exponential subsequence check.
  • Space Complexity: O(2ᵏ)—store subsequences.

It’s a subsequence overachiever!

Comparing the Two Solutions

Section link icon
  • Sorting with Check (Best):
    • Pros: O(n m k), O(1), efficient.
    • Cons: Subsequence logic.
  • Brute-Force (Alternative):
    • Pros: O(2ᵏ n m), explicit.
    • Cons: Too slow for large s.

Sorting wins for practicality!

Additional Examples and Edge Cases

Section link icon
  • ** "a", ["b"]: "".
  • ** "apple", ["app", "apple"]: "apple".
  • ** "xyz", ["x", "y", "z"]: "x".

Sorting handles them all!

Complexity Recap

Section link icon
  • Sorting with Check: Time O(n m k), Space O(1).
  • Brute-Force: Time O(2ᵏ n m), Space O(2ᵏ).

Sorting’s the efficiency champ!

Key Takeaways

Section link icon
  • Sorting: Optimize search—learn at Python Basics!
  • Brute Force: Full but slow.
  • Strings: Subsequences are fun.
  • Python: Sort and check shine!

Final Thoughts: Find That Longest Word!

Section link icon

LeetCode 524: Longest Word in Dictionary through Deleting in Python is a clever string challenge. Sorting with subsequence check is your fast track, while brute force shows the long way. Want more? Try LeetCode 392: Is Subsequence or LeetCode 792: Number of Matching Subsequences. Ready to delete? Head to Solve LeetCode 524 on LeetCode and craft that word today!