I am solving this problem on leetcode. Can't figure out the time and space complexity for my solution.
Particularly, I can't understand how to apply Master Theorem here in case when we have FOR loop. What is a and b here? Since input divided multiple times and for different size of subproblems. Another complication is memoization.
class Solution {
private Map<String, List<Integer>> cache = new HashMap<>();
public List<Integer> diffWaysToCompute(String equation) {
if (cache.containsKey(equation)) return cache.get(equation);
if (!(equation.contains("+") || equation.contains("-") || equation.contains("*"))) return Collections.singletonList(Integer.valueOf(equation));
List<Integer> result = new ArrayList<>();
for (int i = 0; i < equation.length();i++) {
char ch = equation.charAt(i);
if (ch == '+' || ch == '-' || ch == '*') {
List<Integer> left = diffWaysToCompute(equation.substring(0, i));
List<Integer> right = diffWaysToCompute(equation.substring(i+1, equation.length()));
result.addAll(crossCalc(left, right, ch));
}
}
cache.put(equation, result);
return result;
}
private List<Integer> crossCalc(List<Integer> left, List<Integer> rigth, char sign) {
List<Integer> result = new ArrayList<>();
for (Integer l : left) {
for (Integer r : rigth) {
if (sign == '-') {
result.add(l - r);
} else if (sign == '+') {
result.add(l + r);
} else {
result.add(l*r);
}
}
}
return result;
}
}
I am looking for explanation how to calculate time complexity, not only the answer. Preferably if you could explain complexity for both with and without memoization. Thanks!
The time complexity of your algorithm is equal to the number of expressions containing n pairs of parentheses which are correctly matched.
It's called a Catalan number, and it's equal to C(2 * n, n) / (n + 1) = (2 * n)! / ((n + 1)! * n!).
Also, there's a recursive formula for calculating a Catalan number:
f(n+1) = f(0)f(n) + f(1)f(n-1) + f(2)f(n-2) + ... + f(n-2)f(2) + f(n-1)f(1) + f(n)f(0)
And you know, it's the same as your algorithm time complexity equation!
T(n+1) = T(0)T(n) + T(1)T(n-1) + T(2)T(n-2) + ... + T(n-2)T(2) + T(n-1)T(1) + T(n)T(0)
The memory complexity of this algorithm can be as large as the time complexity of it because the number of elements of result
ArrayList can be large. So in worst-case memory and time complexity would be the n-th Catalan number.