Bird
Raised Fist0
Interview Prepdp-lcs-stringhardAmazonFacebookGoogleBloomberg

Word Break II (All Sentences)

Choose your preparation mode4 modes available
</>
IDE
def wordBreak(s: str, wordDict: List[str]) -> List[str]:public List<String> wordBreak(String s, List<String> wordDict)vector<string> wordBreak(string s, vector<string> wordDict)function wordBreak(s, wordDict)
def wordBreak(s: str, wordDict: List[str]) -> List[str]:
    # Write your solution here
    pass
class Solution {
    public List<String> wordBreak(String s, List<String> wordDict) {
        // Write your solution here
        return new ArrayList<>();
    }
}
#include <vector>
#include <string>
using namespace std;

vector<string> wordBreak(string s, vector<string> wordDict) {
    // Write your solution here
    return {};
}
function wordBreak(s, wordDict) {
    // Write your solution here
}
Coming soon
0/10
Common Bugs to Avoid
Wrong: Only one segmentation returned instead of all valid segmentationsGreedy approach returning only first valid segmentation found.✅ Explore all prefixes at each recursion step and memoize results to collect all valid segmentations.
Wrong: Partial segmentations missing due to off-by-one substring errorsIncorrect substring slicing or memoization keys.✅ Carefully handle substring indices and memo keys to include all valid segmentations.
Wrong: Non-empty output for input with no valid segmentationIncorrect base case handling or returning default non-empty list.✅ Return empty list if no valid segmentation found after exploring all prefixes.
Wrong: Timeout on large inputBrute force recursion without memoization causing exponential time.✅ Implement memoized recursion or bottom-up DP to reduce time complexity to O(n^3).
✓
Test Cases
t1_01basic
Input{"s":"catsanddog","wordDict":["cat","cats","and","sand","dog"]}
Expected["cat sand dog","cats and dog"]

The string can be segmented as "cats and dog" or "cat sand dog" using the dictionary words.

t1_02basic
Input{"s":"pineapplepenapple","wordDict":["apple","pen","applepen","pine","pineapple"]}
Expected["pine apple pen apple","pine applepen apple","pineapple pen apple"]

Multiple valid segmentations exist using overlapping dictionary words like 'applepen' and 'apple'.

t2_01edge
Input{"s":"","wordDict":["a","b"]}
Expected[]

Empty string input returns empty list as no segmentation is needed or possible.

t2_02edge
Input{"s":"a","wordDict":["a"]}
Expected["a"]

Single character string equal to a dictionary word returns list with that word only.

t2_03edge
Input{"s":"catsandog","wordDict":["cats","dog","sand","and","cat"]}
Expected[]

String with no valid segmentation returns empty list.

t2_04edge
Input{"s":"apple","wordDict":["apple","app","le"]}
Expected["apple"]

String equals a dictionary word returns list with that word only, despite substrings also in dictionary.

t3_01corner
Input{"s":"aaaaaaa","wordDict":["aaaa","aaa"]}
Expected["aaa aaaa","aaaa aaa"]

Tests greedy trap: must explore all segmentations, not just first match.

t3_02corner
Input{"s":"abcd","wordDict":["a","abc","b","cd"]}
Expected["a b cd","abc d"]

Tests off-by-one errors in substring indices and memoization boundaries.

t3_03corner
Input{"s":"aaaaaaa","wordDict":["a","aa","aaa"]}
Expected["a a a a a a a","a a a a a aa","a a a a aa a","a a a a aaa","a a a aa a a","a a a aa aa","a a a aaa a","a a aa a a a","a a aa a aa","a a aa aa a","a a aa aaa","a a aaa a a","a a aaa aa","a aa a a a a","a aa a a aa","a aa a aa a","a aa a aaa","a aa aa a a","a aa aa aa","a aa aaa a","a aaa a a a","a aaa a aa","a aaa aa a","a aaa aaa","aa a a a a a","aa a a a aa","aa a a aa a","aa a a aaa","aa a aa a a","aa a aa aa","aa a aaa a","aa aa a a a","aa aa a aa","aa aa aa a","aa aa aaa","aa aaa a a","aa aaa aa","aaa a a a a","aaa a a aa","aaa a aa a","aaa a aaa","aaa aa a a","aaa aa aa","aaa aaa a"]

Tests handling of multiple overlapping dictionary words and large branching factor.

t4_01performance
Input{"s":"aaaaaaaaaaaaaaaaaaaa","wordDict":["a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"]}
⏱ Performance - must finish in 2000ms

Input length n=20 with dictionary words of lengths 1 to 10. Algorithm must run in O(n^3) time to avoid TLE.

Practice

(1/5)
1. You are given a string and need to find the longest contiguous substring that reads the same forwards and backwards. Which approach guarantees an optimal solution with polynomial time complexity?
easy
A. Greedy approach that expands from the first character and tries to extend the palindrome
B. Dynamic programming that builds a table to track palindromic substrings of increasing length
C. Brute force checking all substrings and verifying palindrome property each time
D. Longest common subsequence between the string and its reverse

Solution

  1. Step 1: Understand problem constraints

    The problem requires the longest contiguous palindrome substring, not subsequence, so LCS is incorrect.
  2. Step 2: Evaluate approaches

    Brute force is correct but inefficient (O(n^3)). Greedy fails on many cases. DP tabulation guarantees O(n^2) time and correctness by building from smaller substrings.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    DP tabulation is classic for longest palindromic substring [OK]
Hint: DP tabulation tracks palindromes by substring length [OK]
Common Mistakes:
  • Confusing substring with subsequence
  • Assuming greedy can find longest palindrome
  • Using LCS which finds subsequence, not substring
2. You need to determine if a given input string matches a pattern that includes '.' which matches any single character, and '*' which matches zero or more of the preceding element. Which algorithmic approach guarantees an optimal solution for this problem?
easy
A. Dynamic Programming using a 2D table or space-optimized 1D array
B. Sorting the pattern and string then comparing character by character
C. Backtracking with pruning based on character classes
D. Greedy matching scanning the string once from left to right

Solution

  1. Step 1: Understand problem constraints

    The pattern includes '*' which can match zero or more of the preceding element, and '.' which matches any single character. This requires checking multiple matching possibilities.
  2. Step 2: Identify algorithmic approach

    Greedy or sorting approaches fail because '*' can match variable-length substrings and '.' matches any character. Backtracking is exponential in worst case. Dynamic Programming efficiently stores intermediate results to avoid recomputation, guaranteeing optimal solution.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    DP handles overlapping subproblems and variable-length matches [OK]
Hint: DP handles variable-length '*' matches optimally [OK]
Common Mistakes:
  • Assuming greedy works for '*' patterns
3. The following code attempts to implement the space-optimized LCS algorithm. Which line contains a subtle bug that can cause incorrect results on some inputs?
medium
A. Line 7: for j in range(1, n + 1): # iterating forwards
B. Line 5: for i in range(1, m + 1):
C. Line 9: if text1[i - 1] == text2[j - 1]:
D. Line 12: prev = temp

Solution

  1. Step 1: Identify iteration order in inner loop

    The inner loop iterates forwards (j=1 to n), which causes dp[j-1] to be overwritten before it is used in the max calculation.
  2. Step 2: Understand impact of forward iteration

    Because dp[j-1] is updated before dp[j], the algorithm uses updated values instead of previous iteration's values, leading to incorrect LCS length.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Inner loop must iterate backwards to preserve dp[j-1] values [OK]
Hint: Inner loop must run backwards to avoid overwriting dp array [OK]
Common Mistakes:
  • Iterating inner loop forwards in space optimized DP
  • Mixing up indices in character comparison
  • Incorrect initialization of prev variable
4. Suppose you want to count the number of distinct subsequences of t in s, but now characters in s can be reused multiple times (i.e., you can use the same character in s multiple times to form subsequences). Which modification to the DP approach correctly solves this variant?
hard
A. Use a 2D DP where dp[i][j] counts subsequences using first i chars of s and j chars of t, but allow reusing s[i] by not incrementing i on match
B. Change the recurrence to allow staying at the same i index when matching characters
C. Use the same DP but iterate j forward instead of backward in the inner loop
D. No change needed; original DP already counts subsequences with reuse

Solution

  1. Step 1: Understand reuse means characters in s can be used multiple times

    Original DP assumes each character in s can be used at most once per subsequence.
  2. Step 2: Modify DP to allow reusing s[i]

    Use 2D DP where dp[i][j] counts subsequences using first i chars of s for first j chars of t, and when s[i] matches t[j], allow staying at i (not incrementing) to reuse character.
  3. Step 3: Recognize that iterating j forward or no change won't handle reuse correctly

    Only explicit state allowing reuse by not advancing i on match works.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Allowing reuse requires 2D DP with careful state transitions [OK]
Hint: Reuse means allowing same s[i] multiple times, so must not always increment i
Common Mistakes:
  • Assuming original DP handles reuse
  • Trying to fix by changing iteration order only
5. Suppose you want to compute the edit distance where characters can be replaced multiple times (reuse allowed) and the cost of replacement depends on character pairs. Which modification to the classic DP approach correctly handles this variant?
hard
A. Use bottom-up DP with a cost matrix for replacements and update dp accordingly
B. Modify DP to allow revisiting states multiple times with memoization
C. Switch to a greedy approach that picks cheapest replacement at each mismatch
D. Use the same DP but add a third dimension for replacement cost per character pair

Solution

  1. Step 1: Understand replacement cost depends on character pairs

    Replacement cost varies, so DP must incorporate a cost matrix for each character pair.
  2. Step 2: Adapt bottom-up DP to use cost matrix in dp updates

    When characters differ, dp[j] updates using the specific replacement cost from the matrix, ensuring correct minimal cost.
  3. Step 3: Confirm approach handles reuse and varying costs

    Bottom-up DP with cost matrix correctly accumulates minimal costs allowing multiple replacements.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    DP with cost matrix handles variable replacement costs [OK]
Hint: Incorporate cost matrix into DP transitions for variable replacements [OK]
Common Mistakes:
  • Adding extra DP dimension unnecessarily
  • Using memoization without cost matrix
  • Trying greedy which fails globally
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard