This是一个典型的算法问题。
DP解决方案确实是n ^ 3。
我在下面使用带有memoization的递归。
我需要详细解释下面代码的运行时间是什么?我对目前的答案不满意。有人可以帮忙吗?
public static int countParenthesization(String expr, int begin, int end, boolean result, Map<String, Integer> lookup) {
String lookupKey = begin + "-" + end + "-" + result;
if (end - begin == 0) {
String currenExpr = expr.charAt(begin) + "";
int count = (currenExpr.equals("T") && result) || (currenExpr.equals("F") && !result) ? 1 : 0;
lookup.put(lookupKey, count);
return count;
}
if (lookup.containsKey(lookupKey)) {
return lookup.get(lookupKey);
}
int count = 0;
for (int i = begin + 1; i <= end; i = i + 2) {
int leftBegin = begin;
int leftEnd = i - 1;
int rightBegin = i + 1;
int rightEnd = end;
switch (expr.charAt(i)) {
case '|':
if (result) {
count += countParenthesization(expr, leftBegin, leftEnd, true, lookup)
* countParenthesization(expr, rightBegin, rightEnd, true, lookup);
count += countParenthesization(expr, leftBegin, leftEnd, true, lookup)
* countParenthesization(expr, rightBegin, rightEnd, false, lookup);
count += countParenthesization(expr, leftBegin, leftEnd, false, lookup)
* countParenthesization(expr, rightBegin, rightEnd, true, lookup);
} else {
count += countParenthesization(expr, leftBegin, leftEnd, false, lookup)
* countParenthesization(expr, rightBegin, rightEnd, false, lookup);
}
break;
case '&':
if (result) {
count += countParenthesization(expr, leftBegin, leftEnd, true, lookup)
* countParenthesization(expr, rightBegin, rightEnd, true, lookup);
} else {
count += countParenthesization(expr, leftBegin, leftEnd, true, lookup)
* countParenthesization(expr, rightBegin, rightEnd, false, lookup);
count += countParenthesization(expr, leftBegin, leftEnd, false, lookup)
* countParenthesization(expr, rightBegin, rightEnd, true, lookup);
count += countParenthesization(expr, leftBegin, leftEnd, false, lookup)
* countParenthesization(expr, rightBegin, rightEnd, false, lookup);
}
break;
case '^':
if (result) {
count += countParenthesization(expr, leftBegin, leftEnd, true, lookup)
* countParenthesization(expr, rightBegin, rightEnd, false, lookup);
count += countParenthesization(expr, leftBegin, leftEnd, false, lookup)
* countParenthesization(expr, rightBegin, rightEnd, true, lookup);
} else {
count += countParenthesization(expr, leftBegin, leftEnd, true, lookup)
* countParenthesization(expr, rightBegin, rightEnd, true, lookup);
count += countParenthesization(expr, leftBegin, leftEnd, false, lookup)
* countParenthesization(expr, rightBegin, rightEnd, false, lookup);
}
break;
}
}
lookup.put(lookupKey, count);
//System.out.println(lookup);
return count;
}
答案 0 :(得分:1)
如上所述,您的代码为O(n ^ 4)。代码与DP解决方案基本相同,但是DP解决方案小心地在表中使用O(1)索引(一对(i,j)的整数),这段代码使用子串,构造其中需要O(n)时间,并且哈希表中的查找也需要O(n)时间。 [注意:这里的n指的是当前切片表达式字符串的长度,而不是哈希表的大小]。
您可以使用开始/结束索引并避免字符串切片(和哈希表查找)来补救增加的复杂性,就像在DP解决方案中一样。
具体地:
int i, int j
而不是预切片表达式。lookup
哈希表的键将更改为元组<int i, int j, bool result>
而不是字符串。