面试题 08.14:布尔运算

简介: 面试题 08.14:布尔运算

题目

题目链接

给定一个布尔表达式和一个期望的布尔结果 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

解题

方法一:动态规划

严格来说这个答案不是动态规划。是分治,利用dp数组,记录之前访问过的结果。

参考链接1

参考链接2

image

k+=2是因,0或1 和 位运算符是 间隔出现的。

保证每次k出现都是数字0或1,每次k+1都是位运算符。

同时k

image

class Solution {
private:
    vector<vector<vector<int>>> dp;
    string s;
    int dfs(int start,int end,int result){
        if(start==end) return s[start]-'0'==result?1:0;
        if(dp[start][end][result]!=-1)return dp[start][end][result];//记忆化,防止重复访问
        int count=0;
        for(int k=start;k<end;k+=2){
            char op=s[k+1];
            for(int i=0;i<=1;i++){//00、01、10、11四种情况的和
                for(int j=0;j<=1;j++){
                    if(getBoolAns(i,j,op)==result){
                        count+=dfs(start,k,i)*dfs(k+2,end,j);
                    }
                }
            }
        }
        dp[start][end][result]=count;
        return count;
    }
    int getBoolAns(int val1,int val2,char op){
        if(op=='&') return val1&val2;
        if(op=='|') return val1|val2;
        if(op=='^') return val1^val2;
        return val1&val2;
    }
public:
    int countEval(string s, int result) {
        this->s=s;
        int n=s.size();
        dp=vector<vector<vector<int>>>(n,vector<vector<int>>(n,vector<int>(2,-1)));
        return dfs(0,n-1,result);
    }
};

换种写法

class Solution {
public:
    int countEval(string s, int result) {
        int n=s.size();
        vector<vector<vector<int>>> dp(n,vector<vector<int>>(n,vector<int>(2,-1)));
        function<bool(int,int,char)> getBoolAns=[&](int val1,int val2,char op){
            if(op=='^') return val1^val2;
            if(op=='|') return val1|val2;
            if(op=='&') return val1&val2;
            return val1&val2;
        };
        function<int(int,int,int)> dfs=[&](int start,int end,int r){
            if(start==end) return s[start]-'0'==r?1:0;
            if(dp[start][end][r]!=-1) return dp[start][end][r];
            int count=0;
            for(int k=start;k<end;k+=2){
                char op=s[k+1];
                for(int i=0;i<=1;i++){
                    for(int j=0;j<=1;j++){
                        if(getBoolAns(i,j,op)==r){
                            count+=dfs(start,k,i)*dfs(k+2,end,j);
                        }
                    }
                }
            }
            dp[start][end][r]=count;
            return count;
        };
        return dfs(0,n-1,result);
    }
};



相关文章
|
存储 编译器 C语言
搞懂C/C++ 运算符优先级
搞懂C/C++ 运算符优先级
467 0
|
机器学习/深度学习
牛客网——蛇形数组
牛客网——蛇形数组
238 0
牛客网——蛇形数组
|
9月前
|
存储 编译器
有趣的移位操作符和位操作符(由浅入深轻松搞定!)
有趣的移位操作符和位操作符(由浅入深轻松搞定!)
代码随想录刷题|LeetCode 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值(下)
代码随想录刷题|LeetCode 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值
代码随想录刷题|LeetCode 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值(下)
|
编译器
代码随想录刷题|LeetCode 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值(上)
代码随想录刷题|LeetCode 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值
拜托,面试别再问我表达式求值了!!!
思路比结论重要,学到了吗?
670 0
|
JavaScript 前端开发
逗号运算符的妙用
逗号运算符的妙用
286 0
|
C语言
C语言程序设计实战——算术表达式
【项目1-分离各位数】 写一个程序,输入x(三位数),输出其个、十、百位数,用空格隔开 样例输入:768 样例输出:8 6 7 参考解答 【项目2-分离整数和小数部分】 编写一个程序,其功能为:从键盘上输入一个浮点数(小数点后有三位数),然后分别输出该数的整数部分和小数部分。 样例输入:123.456 样例输出:123 456 参考解答 【项目3-如何买玫瑰?
1464 0
|
4月前
|
存储 C++ 容器
Leetcode第二十题(有效的括号)
这篇文章介绍了如何使用栈来解决LeetCode第20题“有效的括号”问题,提供了两种方法:数组栈和容器栈,以及相应的C++代码实现。
28 0
|
算法
代码随想录算法训练营第十一天 | LeetCode 20. 有效的括号、LeetCode 1047. 删除字符串中的所有相邻重复项、LeetCode 150. 逆波兰表达式求值
代码随想录算法训练营第十一天 | LeetCode 20. 有效的括号、LeetCode 1047. 删除字符串中的所有相邻重复项、LeetCode 150. 逆波兰表达式求值
78 0

热门文章

最新文章