I was stuck in a problem studying dynamic programming.
I have a string of numbers. You need to find the length of the longest substring of the substrings in this string that has the sum of the first half of the numbers and the second half of the numbers.
For example,
Input string: 142124
Output : 6
When the input string is "142124", the sum of the numbers of the first half (142) and the number of the second half (124) is the same, so the entire given string becomes the longest substring we find. Therefore, the output is 6, the length of the entire string.
Input string: 9430723
Output: 4
The longest substring in this string that has the sum of the first half and the second half becomes "4307".
I solved this problem this way
int maxSubStringLength(char* str){
int n = strlen(str);
int maxLen = 0;
int sum[n][n];
for(int i=0; i<n; i++)
sum[i][i] = str[i] - '0';
for(int len =2; len <=n; len++){
for(int i = 0; i < n - len + 1; i++){
int j = i + len - 1;
int k = len / 2;
sum[i][j] = sum[i][j-k] + sum[j-k+1][j];
if(len%2 == 0 && sum[i][j-k] == sum[j-k+1][j] && len > maxLen)
maxLen = len;
}
}
return maxLen;
}
This code has a time complexity of O (n * n) and a space complexity of O (n * n).
However, this problem requires solving with O (1) space complexity with O (n * n) time complexity.
Is it possible to solve this problem with the space complexity of O (1)?
You can easily solve this problem with O(1) space complexity and O(n^2) time complexity.
Here is one aproach:
Go from m = 0 to n-2. This denotes the middle of the string (you split after the mth character).
For i = 1 to n (break if you get out of bounds). Build the left and right sums, if they are equal, compare i to best so far and update it if better.
Solution is 2 times best (because it denotes the half string).
In Java it would be something like this:
public int maxSubstringLength(String s) {
int best = 0;
for (int m = 0; m < s.length() - 1; m++) {
int l = 0; // left sum
int r = 0; // right sum
for (int i = 1; m - i + 1 >= 0 && m + i < s.length(); i++) {
l += s.charAt(m - i + 1);
r += s.charAt(m + i);
if (l == r && i > best)
best = i;
}
}
return 2 * best;
}