LeetCode【每日一题】_679. 24 点游戏_java

679. 24 点游戏

问题描述

679.24 点游戏
你有 4 张写有 1 到 9 数字的牌。你需要判断是否能通过 *,/,+,-,(,) 的运算得到 24。

示例 1:

输入: [4, 1, 8, 7]
输出: True
解释: (8-4) * (7-1) = 24

示例 2:

输入: [1, 2, 1, 2]
输出: False

注意:

  1. 除法运算符 / 表示实数除法,而不是整数除法。例如 4 / (1 - 2/3) = 12 。
  2. 每个运算符对两个数进行运算。特别是我们不能用 - 作为一元运算符。例如,[1, 1, 1, 1] 作为输入时,表达式 -1 - 1 - 1 - 1 是不允许的。
  3. 你不能将数字连接在一起。例如,输入为 [1, 2, 1, 2] 时,不能写成 12 + 12 。

题解

使用回溯法解决

一共有4个数和4个操作符,分3步解决

  1. 从4个数中选2个数,从4个操作符中选一个操作符进行计算,将计算结果与剩下的2个数组成一个新的集合,然后判断这3个数能否得到24。第1步一共有在这里插入图片描述
    种情况。
  2. 从剩下3个数中选2个数进行计算,将计算结果与最后1个数组成新的集合。第2步一共有在这里插入图片描述
    种情况。
  3. 计算最后两个数,第3步一共有在这里插入图片描述
    种情况。

48 * 24 * 8 = 9216

一共有9216种算式组合,只要有一个结果等于24,就返回true,否则返回false。

由于除法表示实数除法,而不是整数除法,所以要用浮点数存储。

最后还要处理精度问题,设定一个误差值,只要误差不超过这个范围就忽略

class Solution {
    public boolean judgePoint24(int[] nums) {
		List<Double> list = new ArrayList<>();
		for (double num : nums) {
			list.add(num);
		}
		return solve(list);
	}

	char[] opers = { '+', '*', '-', '/' };

	private boolean solve(List<Double> list) {
		int size = list.size();
		if (size == 0)
			return false;
		if (size == 1)
			return Math.abs(list.get(0) - 24) < 1e-6;
		for (int i = 0; i < size; i++) {
			for (int j = i + 1; j < size; j++) {
				List<Double> list2 = new ArrayList<>();
				for (int k = 0; k < size; k++) {
					if (k != i && k != j) {
						list2.add(list.get(k));
					}
				}
				for (int k = 0; k < 4; k++) {
					list2.add(operate(list.get(i), list.get(j), opers[k]));
					if (solve(list2)) {
						return true;
					}
					list2.remove(size - 2);
					if (k > 1) {
						list2.add(operate(list.get(j), list.get(i), opers[k]));
						if (solve(list2)) {
							return true;
						}
						list2.remove(size - 2);
					}
				}
			}
		}
		return false;
	}

	private double operate(double a, double b, char oper) {
		switch (oper) {
		case '+':
			return a + b;
		case '*':
			return a * b;
		case '-':
			return a - b;
		case '/':
			if (!(Math.abs(b) < 1e-6)) return a / b;
		default:
			return 0;
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程夜游神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值