[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:

  1. The division operator / represents real division, not integer division. For example, 4 / (1 - 2/3) = 12.
  2. 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.
  3. You cannot concatenate numbers together. For example, if the input is [1, 2, 1, 2], we cannot write this as 12 + 12.

解题思路

可以采取的方法:

  1. 打表
  2. 暴力枚举
  3. 回溯

参考代码

这里用的暴力枚举的做法:

  • 每次得到一个中间结果就把它和剩下的数字放到一起一视同仁,然后以任意顺序交换计算,用于代替加括号;
  • 使用 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
posted @ 2021-03-09 21:05  与MPI做斗争  阅读(53)  评论(0编辑  收藏  举报