πŸš€Day 23. Word Break 🧠

The problem can be found at the following link: Question Link

πŸ’‘ Problem Description:

You are given a string s and a list dictionary[] of words. Your task is to determine whether the string s can be formed by concatenating one or more words from the dictionary[].

Note: From dictionary[], any word can be taken any number of times and in any order.

πŸ” Example Walkthrough:

Example 1:

Input:

s = "ilike"
dictionary[] = ["i", "like", "gfg"]

Output:

true

Explanation:

The given string s can be broken down as "i like" using words from the dictionary.

Example 2:

Input:

Output:

Explanation:

The given string s can be broken down as "i like gfg" using words from the dictionary.

Example 3:

Input:

Output:

Explanation:

The given string s cannot be formed using the dictionary words.

Constraints:

  • $( 1 \leq |s| \leq 3000 )$

  • $( 1 \leq |dictionary| \leq 1000 )$

  • $( 1 \leq |dictionary[i]| \leq 100 )$

🎯 My Approach:

Dynamic Programming

Algorithm Steps:

  1. Use a boolean DP vector dp of size n+1 where dp[i] indicates if the substring s[0...i-1] can be segmented.

  2. Insert dictionary words into an unordered set for O(1) lookups.

  3. Iterate through the string and check all possible substrings using the dictionary.

  4. If a valid word is found and its prefix was segmentable, mark dp[i+j] as true.

  5. Return dp[n].

πŸ•’ Time and Auxiliary Space Complexity

  • Expected Time Complexity: $( O(n \times m) )$, as each substring is checked in the dictionary.

  • Expected Auxiliary Space Complexity: $( O(n) )$, as we use a DP array of size n+1.

πŸ“ Solution Code

Code (C++)

⚑ Alternative Approaches

1️⃣ Dynamic Programming (Optimized Iterative DP)

Algorithm Steps:

  1. Use a boolean DP vector dp of size n+1 where dp[i] indicates if the substring s[0...i-1] can be segmented.

  2. Insert dictionary words into an unordered set for O(1) lookups.

  3. Iterate through the string and check all possible substrings using the dictionary.

  4. If a valid word is found and its prefix was segmentable, mark dp[i+j] as true.

  5. Return dp[n].

βœ… Time Complexity: O(n Γ— m) βœ… Space Complexity: O(n)

2️⃣ Trie-Based Approach with DFS and DP

Algorithm Steps:

  1. Build a Trie from the dictionary words.

  2. Use a DP vector where dp[i] is true if s[i...n-1] can be segmented.

  3. Start from the end of the string, traverse the Trie, and mark segmentable indexes.

  4. Return dp[0].

βœ… Time Complexity: O(n Γ— m), where m is the maximum word length βœ… Space Complexity: O(n + total characters in dictionary)

Comparison of Approaches

Approach

⏱️ Time Complexity

πŸ—‚οΈ Space Complexity

βœ… Pros

⚠️ Cons

Dynamic Programming (Optimized)

🟒 O(n Γ— m)

🟒 O(n)

Efficient and easy to implement

Still requires full DP array

Trie-Based Approach

🟒 O(n Γ— m)

🟑 O(n + dictionary)

Faster lookups, avoids substrings

More complex implementation

βœ… Best Choice?

  • If you want best efficiency: Use DP Optimized approach.

  • If you prefer Trie-based lookup: Use Trie + DP.

Code (Java)

Code (Python)

🎯 Contribution and Support:

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: Any Questions. Let’s make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Last updated