给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成。实现一个函数,算出有几种可使该表达式得出 result 值的括号方法。
示例 1:
输入: s = "1^0|0|1", result = 0
输出: 2
解释: 两种可能的括号方法是
1^(0|(0|1))
1^((0|0)|1)
示例 2:
输入: s = "0&0&0&1^1|0", result = 1
输出: 10
提示:
运算符的数量不超过 19 个
思路:记忆化搜索,每次将当前串分成左右两个子串,并用map存储信息即可【由于我们只关心0和1的个数,因此map应存储当前子表达式能产生多少个0和1即可】。
class Solution {
private Map<String, int[]> memo;
public int countEval(String s, int result) {
int num = 0;
memo = new HashMap<>();
int[] ans = dfs(s, s.length(), result);
return ans[result];
}
private int[] dfs(String s, int n, int result) {
if (s.length() == 1) {
int[] arr = new int[2];
if (s.charAt(0) == '1') arr[1]++;
else arr[0]++;
return arr;
}
if (memo.containsKey(s))
return memo.get(s);
int[] arr = new int[2];
for (int i = 0; i < s.length() - 2; i += 2) {
int[] l = dfs(s.substring(0, i + 1), n, result);
int[] r = dfs(s.substring(i + 2, s.length()), n, result);
if (s.charAt(i + 1) == '&') {
arr[0] += l[0] * r[0] + l[0] * r[1] + l[1] * r[0];
arr[1] += l[1] * r[1];
} else if (s.charAt(i + 1) == '|') {
arr[0] += l[0] * r[0];
arr[1] += l[1] * r[0] + l[1] * r[1] + l[0] * r[1];
} else {
arr[0] += l[0] * r[0] + l[1] * r[1];
arr[1] += l[1] * r[0] + l[0] * r[1];
}
}
memo.put(s, arr);
return arr;
}
}