题目地址:
https://www.lintcode.com/problem/24-game/description
算
24
24
24点。直接DFS即可。具体实现来说,先把所有数加进一个list,然后开始做DFS,递归出口是,list的size为
1
1
1并且里面的那个数正好是
24
24
24。然后开始枚举list中挑选两个数
x
x
x和
y
y
y,分别做
x
+
y
x+y
x+y,
x
−
y
x-y
x−y,
y
−
x
y-x
y−x,
x
∗
y
x*y
x∗y,
x
/
y
x/y
x/y,
y
/
x
y/x
y/x这几个运算,加进list中后继续进入下一层递归。如果某次递归得到了正确答案就直接返回true。注意两个地方,一个是判断结果是否是
24
24
24的时候由于是在判断double类型,所以不能用==
,必须判断差小于一个非常小的正数;另一个是,除法时要判断除数非零。代码如下:
import java.util.ArrayList;
import java.util.List;
public class Solution {
/**
* @param nums: 4 cards
* @return: whether they could get the value of 24
*/
public boolean compute24(double[] nums) {
// write your code here
List<Double> cur = new ArrayList<>();
for (double num : nums) {
cur.add(num);
}
return dfs(cur);
}
private boolean dfs(List<Double> cur) {
if (cur.size() == 1) {
return isZero(cur.get(0) - 24);
}
for (int i = 0; i < cur.size(); i++) {
for (int j = i + 1; j < cur.size(); j++) {
// 从中间取出两个数。
// 注意,这里取数的次序不能颠倒,一定要先取位置靠后的,后取位置靠前的
// 在内层循环结束的时候恢复现场则是反过来,先把位置靠前的添加回来,再把位置靠后的添加回来
double y = cur.remove(j), x = cur.remove(i);
// 开始枚举那几种情况。递归完后要记得恢复现场。
cur.add(x + y);
if (dfs(cur)) {
return true;
}
cur.remove(cur.size() - 1);
cur.add(x - y);
if (dfs(cur)) {
return true;
}
cur.remove(cur.size() - 1);
cur.add(y - x);
if (dfs(cur)) {
return true;
}
cur.remove(cur.size() - 1);
cur.add(x * y);
if (dfs(cur)) {
return true;
}
cur.remove(cur.size() - 1);
if (!isZero(y)) {
cur.add(x / y);
if (dfs(cur)) {
return true;
}
cur.remove(cur.size() - 1);
}
if (!isZero(x)) {
cur.add(y / x);
if (dfs(cur)) {
return true;
}
cur.remove(cur.size() - 1);
}
// 先把位置靠前的添加回来,再把位置靠后的添加回来
cur.add(i, x);
cur.add(j, y);
}
}
return false;
}
private boolean isZero(double num) {
return Math.abs(num) < 1E-10;
}
}