Skip to content

Commit 7c527ec

Browse files
authored
Update and rename MatrixChainMultiplication.txt to WordBreakBoolean.java
1 parent 6cf8bd5 commit 7c527ec

File tree

2 files changed

+102
-47
lines changed

2 files changed

+102
-47
lines changed

DynamicProgramming/WordBreakProblem/MatrixChainMultiplication.txt

Lines changed: 0 additions & 47 deletions
This file was deleted.
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
https://www.geeksforgeeks.org/word-break-problem-dp-32/
3+
https://leetcode.com/problems/word-break/discuss/43790/Java-implementation-using-DP-in-two-ways
4+
5+
NOTE - NOT SURE ABOUT THE TIME COMPLEXITY
6+
Comment from Leetcode -
7+
just want to add some comments for the time complexity:
8+
First DP: [length of s][size of dict][avg length of words in dict]
9+
Second DP: [length of s]^3
10+
11+
BTW, for this kind of problem, which time complexity is [length of s][size of dict][avg length of words in dict]. We can usually remove [size of dict] by using Tire, remove [avg length of words in dict] by KMP, and what's more, remove both [size of dict] and [avg length of words in dict] by AC-automata. And of course these are all doable for this problem.
12+
This is just a insight for people who want to think deeper about this problem, hope it can help you :)
13+
14+
15+
QUESTION -
16+
Given an input string and a dictionary of words, find out if the input string can be segmented into a space-separated sequence of dictionary words.
17+
{ i, like, sam, sung, samsung, mobile, ice, cream, icecream, man, go, mango}
18+
Input: ilike
19+
Output: Yes
20+
The string can be segmented as "i like".
21+
22+
Input: ilikesamsung
23+
Output: Yes
24+
The string can be segmented as "i like samsung"
25+
or "i like sam sung".
26+
*/
27+
28+
//DP - Method 1
29+
30+
public boolean wordBreak(String s, Set<String> dict){
31+
32+
//T[i] indicates if it is possible to break the string s[0...i] into valid words from the dictionary
33+
boolean T[] = new boolean[s.length()+1];
34+
35+
//i=0 indicates empty string, which is valid ==> true
36+
T[0] = true;
37+
38+
//the string under consideration starts from length=1 and goes up to length=s.length()
39+
//This is a bottom up approach - we start from the base condition ie. length=1
40+
//During each iteration the string under consideration is s[0....i]
41+
for(int i=1 ; i <= s.length() ; i++){
42+
43+
//j is used to create a partition
44+
//The problem here is to check if s[0...i] can be broken down into valid words from the dictionary
45+
//We need to find where to make a break to get a valid result ==> explore all breaking points using 'j'
46+
//'j' breaks the string s[0...i] into two parts ==> s[0...j) and s[j...i)
47+
//subproblem is s[0...j) which has already been solved and the result is stored in T[j]
48+
//In this loop we basically -
49+
//1. choose a partition index - j
50+
//2. check if the suffix string is present in the dictionary
51+
//3. If it is then check if the prefix can be broken into valid words from the dictionary
52+
//4. If both 2 and 3 are true, we found another valid break of the string at index j, break as soon as 2 & 3 become true
53+
54+
//we start at j=0 because we want to check if the entire word s[0...i] is present in the dictionary or not
55+
for(int j=0 ; j < i ; j++){
56+
if(dict.contains(s.substring(j,i)) && T[j]){
57+
T[i] = true;
58+
break;
59+
}
60+
}
61+
}
62+
63+
return T[s.length()];
64+
}
65+
//Time - O(n^2) OR O(n^3) ????
66+
67+
//DP-Method 2
68+
69+
public boolean wordBreak(String s, Set<String> dict){
70+
71+
//T[i] indicates if it is possible to break the string s[0...i] into valid words from the dictionary
72+
boolean T[] = new boolean[s.length()+1];
73+
74+
//i=0 indicates empty string, which is valid ==> true
75+
T[0] = true;
76+
77+
//the string under consideration starts from length=1 and goes up to length=s.length()
78+
//This is a bottom up approach - we start from the base condition ie. length=1
79+
//During each iteration the string under consideration is s[0....i]
80+
for(int i=1 ; i<=s.length() ; i++){
81+
82+
//look through all the strings in the dictionary and see if any of these words fits as a suffix in the current string
83+
for(String str : dict){
84+
//1. To check if a string is present as a suffix we must first see if current 'i' ie. length of string under
85+
//consideration is greater than the string from the dictionary
86+
//2. If 1 is true we check if the string from dictionary matches with the suffix of string
87+
//3. If 2 is true we solve the subproblem s[0......(i-str.length())] to see if this part of the string can be broken
88+
89+
/*
90+
This code is exactly the same as the above - the inner for loop is used for partitioning in both the code snippets.
91+
Here we use the dictionary string's length to partition
92+
In the previous code a separate index is used to partition
93+
*/
94+
95+
if(i >= str.length() && s.substring(i-str.length(),i).equals(str) && T[i-str.length()]){
96+
T[i] = true;
97+
break;
98+
}
99+
}
100+
}
101+
}
102+
//Time - O(s.length()*dict.size())

0 commit comments

Comments
 (0)