24 点游戏
难度:
标签:
题目描述
代码结果
运行时间: 36 ms, 内存: 16.0 MB
/*
* 思路:
* 1. 使用stream处理卡片的排列和运算符组合。
* 2. 通过递归计算可能的表达式值。
*/
import java.util.*;
import java.util.stream.Collectors;
public class SolutionStream {
public boolean judgePoint24(int[] cards) {
return permute(Arrays.stream(cards).boxed().collect(Collectors.toList()));
}
private boolean permute(List<Double> nums) {
if (nums.size() == 1) return Math.abs(nums.get(0) - 24) < 1e-6;
return nums.stream()
.flatMap(a -> nums.stream().filter(b -> !b.equals(a)).map(b -> Arrays.asList(a, b)))
.map(pair -> compute(pair.get(0), pair.get(1)))
.flatMap(Collection::stream)
.anyMatch(result -> {
List<Double> next = nums.stream()
.filter(n -> !n.equals(pair.get(0)) && !n.equals(pair.get(1)))
.collect(Collectors.toList());
next.add(result);
return permute(next);
});
}
private List<Double> compute(double a, double b) {
return Arrays.asList(a + b, a - b, b - a, a * b, b != 0 ? a / b : null, a != 0 ? b / a : null)
.stream()
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
}
解释
方法:
此题解采用了递归回溯的方法来解决24点游戏。主要思路是,每次递归中选择两个数字进行所有四种运算(加、减、乘、除),并将结果作为新的数字与剩余的数字一起继续递归处理,直到数组中只剩下一个数字,如果这个数字接近24(由于浮点运算,这里使用了一个小的阈值来判断),则返回true。对于除法和减法,由于它们不满足交换律,需要额外处理两个数字位置交换的情况。递归终止的基本情况是当数组中只剩一个数字,检查这个数字是否接近24。
时间复杂度:
O(1) (因为输入的卡片数量固定为4,所以时间复杂度可以视为常量时间复杂度)
空间复杂度:
O(4) (递归深度)
代码细节讲解
🦆
为什么选择使用递归回溯方法来解决这道24点游戏题目?
▷🦆
递归方法中,如何处理数字的重复使用问题,避免在递归过程中多次选择同一数字?
▷🦆
在递归过程中,你是如何决定在哪一层递归中终止并返回结果的?
▷