【leetcode 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 。

分析与解题思路

这道题最简单的想法肯定就是遍历所有的情况,因为情况是有限的,所以遍历起来也不是特别的麻烦。我们先来看一下一共有多少种情况:

  • 首先,可以从4个数字里面任意选两个出来(有序),进行四种运算,共有A424A_4^2*4种选法;
  • 之后,将上述运算的结果当成一个新的数字,并代入到原来的列表中,替换掉之前选择的两个数字,这时列表的数字个数应该为3个;
  • 从三个里面选择两个数字,再进行4种运算,共有A324A_3^2*4种选法;
  • 同理:最后两位数字的可能为A214A_2^1*4种;
  • 所以共有:
    A424A324A214=9216A_4^2*4*A_3^2*4*A_2^1*4=9216

从以上分析的过程,我们很容易想到采取递归的方法求解:
每次调用递归函数后,数组都减少一个数字,那么当减少到只剩一个数字了,就是最后的计算结果,所以我们在递归函数开始时判断,如果数组只有一个数字,且为24,说明可以算出24,结果res赋值为true返回。这里我们的结果res是一个全局的变量,如果已经为true了,就没必要再进行运算了,所以第一行应该是判断结果res,为true就直接返回了。我们遍历任意两个数字,分别用p和q来取出,然后进行两者的各种加减乘除的运算,将结果保存进数组临时数组t,记得要判断除数不为零。然后将原数组nums中的p和q移除,遍历临时数组t中的数字,将其加入数组nums,然后调用递归函数,记得完成后要移除数字,恢复状态,这是递归解法很重要的一点。最后还要把p和q再加回原数组nums,这也是还原状态。

这一段参考了https://blog.csdn.net/weixin_33693070/article/details/85968548

参考代码

from operator import truediv, mul, add, sub

class Solution(object):
    def judgePoint24(self, A):
        if not A: return False
        if len(A) == 1: return abs(A[0] - 24) < 1e-6

        for i in range(len(A)):
            for j in range(len(A)):
                if i != j:
                    B = [A[k] for k in range(len(A)) if i != k != j]
                    for op in (truediv, mul, add, sub):
                        if (op is add or op is mul) and j > i: continue
                        if op is not truediv or A[j]:
                            B.append(op(A[i], A[j]))
                            if self.judgePoint24(B): return True
                            B.pop()
        return False
原文地址:https://www.cnblogs.com/zjkstudy/p/12596267.html