679. 24 点游戏

你有 4 张写有 1 到 9 数字的牌。你需要判断是否能通过 *,/,+,-,(,) 的运算得到 24。

示例 1:

输入: [4, 1, 8, 7]
输出: True
解释: (8-4) * (7-1) = 24
示例 2:

输入: [1, 2, 1, 2]
输出: False
注意:

除法运算符 / 表示实数除法,而不是整数除法。例如 4 / (1 - 2/3) = 12 。
每个运算符对两个数进行运算。特别是我们不能用 - 作为一元运算符。例如,[1, 1, 1, 1] 作为输入时,表达式 -1 - 1 - 1 - 1 是不允许的。
你不能将数字连接在一起。例如,输入为 [1, 2, 1, 2] 时,不能写成 12 + 12 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/24-game
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解:1WA后A,暴搜。。

            操作数生成:dfs求出nums的全排列;      时间复杂度:O(4!) = 24

            操作符生成:3层for循环;                        时间复杂度:O(4^3) = 64

            所有带括号与不带括号情况:共9种          时间复杂度:O(1) = 9

            求表达式的结果:用两个栈模拟                时间复杂度:2*O(n) = 8;

            总体时间复杂度大概是 :24 * 64 * 9 * 8 = 1e5 左右

            妥妥的1s执行完啊,但是实际运行时间较慢,在1s临界,看来c++的STL是真的慢。

class Solution {
public:
    double C(double x, double y, char op){
        if(op=='*') return x*y;
        else if(op=='/') return x/y;
        else if(op=='+') return x+y;
        else return x-y;
    }
    bool flag=false;
    vector<int>v;
    char ops[5];
 
    // 表达式求解
    double fun(vector<double> vect, vector<char>op){
        stack<double>s1; stack<char>s2;
        s1.push(vect[0]); s2.push(op[0]);
        for(int i=1;i<vect.size();i++){
            char c=s2.top();
            if(c=='*'||c=='/'){
                double x=C(s1.top(),vect[i],c);
                s1.pop(); s2.pop(); s1.push(x);
            }else s1.push(vect[i]);
            if(i>=op.size()) break;
            s2.push(op[i]);
        }
        double ans=0;
        if(s1.size()==1) return s1.top();
        while(!s1.empty()){
            double x1=s1.top(); s1.pop();
            char c=s2.top(); s2.pop();
            double x2=s1.top(); s1.pop();
            s1.push(C(x2,x1,c));
            if(s1.size()==1){ ans=s1.top();break;}
        }
        return ans;
    }
 
    bool J(double ans, double result){
        if(abs(ans-result)<=0.000006) return true;
        return false;
    }
    
    // 9种情况分类
    bool work(vector<double>& vect,char c1,char c2,char c3){
        double result=24.0;
        for(int i=0;i<9;i++){
            vector<double>cut; vector<char>op;
            double ans=0;
            if(i==0){
                // x * y + z - d
                op.push_back(c1);op.push_back(c2);op.push_back(c3);
                ans=fun(vect, op);
            }else if(i==1){
                // (x *y) + z -d
                cut.push_back(C(vect[0],vect[1],c1));
                cut.push_back(vect[2]);cut.push_back(vect[3]);
                op.push_back(c2);op.push_back(c3); ans=fun(cut, op);
            }else if(i==2){
                // x * (y + z) - d
                cut.push_back(vect[0]); cut.push_back(C(vect[1],vect[2],c2));
                cut.push_back(vect[3]); op.push_back(c1);op.push_back(c3);
                ans=fun(cut, op);
            }else if(i==3){
                // x * y + (z - d)
                cut.push_back(vect[0]); cut.push_back(vect[1]);
                cut.push_back(C(vect[2],vect[3],c3)); op.push_back(c1);op.push_back(c2);
                ans=fun(cut, op);
            }else if(i==4){
                // (x * y) + (z - d)
                cut.push_back(C(vect[0],vect[1],c1));
                cut.push_back(C(vect[2],vect[3],c3)); op.push_back(c2);
                ans=fun(cut, op);
            }else if(i==5){
                // ((x * y) + z) - d
                double x=C(vect[0],vect[1],c1); cut.push_back(C(x,vect[2],c2));
                cut.push_back(vect[3]); op.push_back(c3);
                ans=fun(cut, op);
            }else if(i==6){
                // (x * (y + z)) - d
                double x=C(vect[1],vect[2],c2); cut.push_back(C(vect[0],x,c1));
                cut.push_back(vect[3]); op.push_back(c3); ans=fun(cut, op);
            }else if(i==7){
                // x * ((y + z) - d)
                cut.push_back(vect[0]); double x=C(vect[1],vect[2],c2);
                cut.push_back(C(x,vect[3],c3)); op.push_back(c1); ans=fun(cut, op);
            }else{
                // x * (y + (z - d))
                cut.push_back(vect[0]); double x=C(vect[2],vect[3],c3);
                cut.push_back(C(vect[1],x,c2)); op.push_back(c1); ans=fun(cut, op);
            }
            if(J(ans, result)) return true;
        }
        return false;
    }
 
    // 生成操作数与操作符
    void dfs(vector<int>& nums, int len, vector<double> vect, int num){
        if(flag) return;
        if(num==len){
            for(int i=0;i<4;i++){
                for(int j=0;j<4;j++){
                    for(int k=0;k<4;k++){
                        if((ops[i]=='/'&&vect[1]==0) || (ops[j]=='/'&&vect[2]==0) || (ops[k]=='/'&&vect[3]==0))
                            continue;
                        bool cut = work(vect, ops[i], ops[j], ops[k]);
                        if(cut) flag=true;
                    }
                }
            }
            return;
        }
        for(int i=0;i<len;i++){
            if(v[i]) continue; v[i]=1; vect.push_back((double)nums[i]); num++;
            dfs(nums,len,vect,num);
            v[i]=0; num--; vect.pop_back();
        }
    }
 
    bool judgePoint24(vector<int>& nums) {
        int len=nums.size();
        if(!len) return false;
        for(int i=0;i<len;i++) v.push_back(0);
        vector<double>vect;
        ops[0]='*'; ops[1]='/'; ops[2]='+'; ops[3]='-';
        dfs(nums,len,vect,0);
        return flag;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值