【LeetCode】24 点游戏(回溯法DFS)
题目链接
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 。
解题思路
1.回溯法(利用DFS)
![](https://img2020.cnblogs.com/blog/1179840/202008/1179840-20200822215616127-1413200757.png)
其实回溯法的原理就是利用DFS实现的,本题递归的结束条件就是动态数组只剩一个元素且元素==24.
![](https://img2020.cnblogs.com/blog/1179840/202008/1179840-20200822220547588-1356018416.png)
AC代码
1.回溯法(利用DFS)
class Solution {
double ans = 1e-6;
boolean dfs(ArrayList<Double> list){
//递归退出条件
if(list.size() == 1){
if(list.get(0).doubleValue() - 24 < ans && list.get(0).doubleValue() - 24 > -ans){
return true;
}
}
if(list.size() == 1 && list.get(0) != 24) return false;
int size = list.size();
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
//list.get(i)\list.get(j)为我们选中的两个元素
if(i != j){
ArrayList<Double> temp = new ArrayList<>();
//将list数组中剩余元素存储到temp数组,
//为什么还需要temp数组呢,因为递归入栈、出栈需要!!!!!!!
//temp数组当作函数栈帧中的局部变量表的一员,可以理解为,当函数A弹栈时,系统知道上一个函数(调用A的函数)运行时候的环境,例如有哪些变量,变量的值是多少。
for(int k = 0; k < size; k++){
if(k != i && k != j) temp.add(list.get(k));
}
// +-*/,其中/-可以交换位置,所以共6种情况。
//两元素相加
double num = list.get(i) + list.get(j);
temp.add(num);
if(dfs(temp)) return true;
temp.remove(temp.size()-1);
//两元素相减
num = list.get(i) - list.get(j);
temp.add(num);
if(dfs(temp)) return true;
temp.remove(temp.size()-1);
//两元素相减
num = list.get(j) - list.get(i);
temp.add(num);
if(dfs(temp)) return true;
temp.remove(temp.size()-1);
//两元素相乘
num = list.get(i) * list.get(j);
temp.add(num);
if(dfs(temp)) return true;
temp.remove(temp.size()-1);
//两元素相除,排除除数为0
if(list.get(i) != 0){
num = list.get(j) / list.get(i);
temp.add(num);
if(dfs(temp)) return true;
temp.remove(temp.size()-1);
}
//两元素相除,排除除数为0
if(list.get(j) != 0){
num = list.get(i) / list.get(j);
temp.add(num);
if(dfs(temp)) return true;
temp.remove(temp.size()-1);
}
}
}
}
return false;
}
public boolean judgePoint24(int[] nums) {
if(nums.length == 0) return false;
ArrayList<Double> list = new ArrayList<>();
for(int i = 0; i < 4; i++) list.add(new Double(nums[i]));
return dfs(list);
}
}