题目描述
给定一个长度为4的整数数组 cards 。你有 4 张卡片,每张卡片上都包含一个范围在 [1,9] 的数字。您应该使用运算符 [‘+’, ‘-’, ‘*’, ‘/’] 和括号 ‘(’ 和 ‘)’ 将这些卡片上的数字排列成数学表达式,以获得值24。
你须遵守以下规则:
- 除法运算符 ‘/’ 表示实数除法,而不是整数除法。
- 例如, 4 /(1 - 2 / 3)= 4 /(1 / 3)= 12 。
- 每个运算都在两个数字之间。特别是,不能使用 “-” 作为一元运算符。
- 例如,如果 cards =[1,1,1,1] ,则表达式 “-1 -1 -1 -1” 是 不允许 的。
- 你不能把数字串在一起
- 例如,如果 cards =[1,2,1,2] ,则表达式 “12 + 12” 无效。
如果可以得到这样的表达式,其计算结果为 24 ,则返回 true ,否则返回 false 。
来源:力扣(LeetCode)
链接:题目链接
示例 1
输入: cards = [4, 1, 8, 7]
输出: true
解释: (8-4) * (7-1) = 24
示例 2
输入: cards = [1, 2, 1, 2]
输出: false
解题思路
不要被运算符 [‘+’, ‘-’, ‘*’, ‘/’] 和括号 ‘(’ 和 ‘)’ 所困惑,
思路:典型的DFS思想,需要知道的是无论怎么操作,都需要先计算任意两个数,将结果作为新的数,加入运算,继续操作,直到只剩下两个数,再判断两个数字的加减乘除是否能得到24。也就是慢慢由4个数字减少到2个,最后到一个最终的结果,判断该结果是否等于24。
核心:
1.先随机计算两个数字的结果。
2.将原来这两个数字从数列中剔除掉,将新的结果加入进去。
3.继续进行1的操作。
4.直到数列中只剩下一个,判断这个数字是否等于24。
bool judge_24(vector<double> num){
//结束条件
if(num.size()==1) {
return abs(num[0]-24)<0.000001; //double不能和整数直接比较,小数在计算机里有误差
}
//计算任意两个数,将新的结果加入队列
for(int i=0;i<num.size();i++){
for(int j=0;j<num.size();j++){
if(i==j) continue;
vector<double> tmp;
for(int k=0;k<num.size();k++)
if(k!=i && k!=j)
tmp.push_back(num[k]);
tmp.push_back(-1);
double a=num[i];
double b=num[j];
tmp.back()=a+b;
if(judge_24(tmp)) return true;
tmp.back()=a-b;
if(judge_24(tmp)) return true;
tmp.back()=a*b;
if(judge_24(tmp)) return true;
if(b!=0){
tmp.back()=a/b;
if(judge_24(tmp)) return true;
}
}
}
return false;
}
bool game_24(vector<int>& cards) {
vector<double> nums;
for(auto x:cards) nums.push_back(x);//转成double方便运算 避免精度消失
return judge_24(nums);
}
感兴趣的,也可以尝试一下穷举。