你有 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;
}
};