/* Top down memoization approach
Idea is break the word into two parts
Part1 Part2
leetscode ==> [l] [eetscde]
[le] [etscode]
[lee] [tscode]
if part1 is found in dictionary, then solution = solution is just part 2( as min chars left is zero )
if part1 is not found in dictionary, the solution = length of part1(left over chars) + solution to part 2
the final solution will be minimum of all the solutions
Time complexity = O(n2)
*/
class Solution {
public:
int minExtraCharUtil(string s, int i, int j, map<string, int>& dict,
vector<int>& DP) {
/* we have exhausted the string , so the min left chars is zero */
if(i > j)
return 0;
if (DP[i] != -1)
return DP[i];
int minVal = INT_MAX;
for (int k = i; k <= j; k++) {
int val = INT_MAX;
string str = s.substr(i, k-i+1);
if(dict.count(str)) {
/*part1 is found in dict */
val = minExtraCharUtil(s, k+1, j, dict, DP);
} else {
/*part1 is not found in dict , so count the left chars and find the solution to part2 */
val = str.size() + minExtraCharUtil(s, k+1, j, dict, DP);
}
minVal = min(minVal, val);
} // for ends
DP[i] = minVal;
return DP[i];
}
map<string, int> dict;
int minExtraChar(string s, vector<string>& dictionary) {
for (int i = 0; i < dictionary.size(); i++) {
dict[dictionary[i]] = dictionary[i].length();
}
int R = s.size();
vector<int> DP(R, -1);
return minExtraCharUtil(s, 0, R-1 , dict, DP);
}
};