[LeetCode 679.] 24点游戏
LeetCode 679. 24点游戏
看到一道回溯的题目,一时有点毛爪,看leetcode的讨论,竟然发现 打表 和 暴力枚举 的做法。受此启发写下了这份答案。
题目描述
You have 4 cards each containing a number from 1 to 9. You need to judge whether they could operated through *, /, +, -, (, ) to get the value of 24.
Example 1:
Input: [4, 1, 8, 7]
Output: True
Explanation: (8-4) * (7-1) = 24
Example 2:
Input: [1, 2, 1, 2]
Output: False
Note:
- The division operator / represents real division, not integer division. For example, 4 / (1 - 2/3) = 12.
- Every operation done is between two numbers. In particular, we cannot use - as a unary operator. For example, with [1, 1, 1, 1] as input, the expression -1 - 1 - 1 - 1 is not allowed.
- You cannot concatenate numbers together. For example, if the input is [1, 2, 1, 2], we cannot write this as 12 + 12.
解题思路
可以采取的方法:
- 打表
- 暴力枚举
- 回溯
参考代码
这里用的暴力枚举的做法:
- 每次得到一个中间结果就把它和剩下的数字放到一起一视同仁,然后以任意顺序交换计算,用于代替加括号;
- 使用
next_permutation
来组织数字的任意计算顺序。
/*
* @lc app=leetcode id=679 lang=cpp
*
* [679] 24 Game
*/
// @lc code=start
double add(double a, double b) { return a+b; }
double mul(double a, double b) { return a*b; }
double sub1(double a, double b) { return a-b; }
double sub2(double a, double b) { return b-a; }
double div1(double a, double b) { return a/b; }
double div2(double a, double b) { return b/a; }
using Func = double(*)(double, double);
const vector<Func> calls { add, sub1, sub2, mul, div1, div2 };
vector<double> num4;
vector<double> num3;
vector<double> num2;
constexpr double eps = 1E-3;
class Solution {
public:
bool judgePoint24(vector<int>& nums) {
num4.clear(); // 全局变量注意重置
for (int x : nums) num4.push_back(x);
return judge4();
}
bool judge4() {
sort(num4.begin(), num4.end());
do {
for (auto&& f : calls) {
double t1 = f(num4[0], num4[1]);
num3 = {t1, num4[2], num4[3]};
if (judge3()) return true;
}
} while (next_permutation(num4.begin(), num4.end()));
return false;
}
bool judge3() {
sort(num3.begin(), num3.end());
do {
for (auto&& f : calls) {
double t2 = f(num3[0], num3[1]);
num2 = {t2, num3[2]};
if (judge2()) return true;
}
} while (next_permutation(num3.begin(), num3.end()));
return false;
}
bool judge2() {
for (auto&& f : calls) {
double t3 = f(num2[0], num2[1]);
if (fabs(t3 - 24.0) < eps) return true;
}
return false;
}
};
// @lc code=end