Determine string segmentability with dictionary
Company: Amazon
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Onsite
Quick Answer: This interview question evaluates algorithm design, data structures, correctness, complexity, edge cases, and implementation details in a realistic interview setting. A strong answer for Determine string segmentability with dictionary states assumptions, handles edge cases, explains trade-offs, and shows how to validate the result clearly.
Constraints
- 1 <= len(s) <= 300 (an empty s returns True)
- 1 <= word_dict.length <= 1000 (an empty dictionary is allowed; only the empty string is then segmentable)
- 1 <= each word length <= 20
- s and all dictionary words consist of lowercase English letters
- Dictionary words may be reused any number of times
Examples
Input: ("leetcode", ["leet", "code"])
Expected Output: True
Explanation: "leet" + "code" covers the whole string.
Input: ("applepenapple", ["apple", "pen"])
Expected Output: True
Explanation: "apple" + "pen" + "apple"; the word "apple" is reused.
Input: ("catsandog", ["cats", "dog", "sand", "and", "cat"])
Expected Output: False
Explanation: No segmentation reaches the end: "cats"+"and" leaves "og", and "cat"+"sand" leaves "og", neither of which is in the dictionary.
Input: ("", ["a", "b"])
Expected Output: True
Explanation: Edge case: the empty string is the empty concatenation, so it is segmentable.
Input: ("aaaaaaa", ["aaaa", "aaa"])
Expected Output: True
Explanation: 7 = 4 + 3, so "aaaa" + "aaa" works despite heavy overlap between candidate splits.
Input: ("a", [])
Expected Output: False
Explanation: Edge case: an empty dictionary cannot cover any non-empty string.
Input: ("bb", ["a", "b", "bbb", "cccc"])
Expected Output: True
Explanation: "b" + "b"; a single-letter word reused covers the string even though "bb" itself is not in the dictionary.
Hints
- Define dp[i] = True iff the prefix s[:i] can be segmented. dp[0] = True because the empty prefix is trivially segmentable.
- For each end index i, look back to a split point j: if dp[j] is True and s[j:i] is a dictionary word, then dp[i] is True.
- Put the dictionary in a hash set for O(1) membership, and bound the inner loop by the longest word length so you never test substrings longer than any dictionary word.
- For the Trie variant, walk the Trie from each start position; stop the inner scan as soon as no child matches the next character (early termination), which speeds up long inputs with few matching prefixes.