这个题我看了 标准答案理解了一下。
我觉得有一点不同的是我们写dp是因为它可以避免递归过程中大量重复的计算,大大提高效率。
而在这个题目中,我们是从最大范围一步一步往前缩小范围,看是否可以找到我们需要的方法。
递归的边界条件是范围为1,看它是否符合我们想得到的结果,然后返回上一层,在上一层我们会把左右两部分的方法数相乘,并且加到最后的结果中。
class Solution {
private char[] arr;
private int[][][] dp;
private int getBool(int val1,int val2,char operator)
{
switch(operator){
case '&':
return val1&val2;
case '|':
return val1|val2;
case '^':
return val1^val2;
}
return val1&val2;
}
private int rec(int start,int end,int result)
{
if(start==end)
return arr[start]-'0'==result?1:0;
if(dp[start][end][result]!=-1){
return dp[start][end][result];
}
int ansCount=0;
for(int k=start;k<end;k+=2){
char operator=arr[k+1];
for(int i=0;i<=1;i++)
{
for(int j=0;j<=1;j++)
{
if(getBool(i,j,operator)==result){
ansCount+=rec(start,k,i)*rec(k+2,end,j);
}
}
}
}
dp[start][end][result]=ansCount;
return ansCount;
}
public int countEval(String s, int result) {
arr=s.toCharArray();
int len=arr.length();
dp=new int[len][len][2];
for(int i=0;i<len;i++)
{
for(int j=0;j<len;j++)
{
Arrays.fill(dp[i][j],-1);
}
}
return rec(0,len-1,result);
}
}