24点问题_快手
程序员文章站
2022-03-31 20:44:13
...
- 问题描述:给玩家4张牌,每张牌牌面值在1~13之间,允许其中有数值相同的牌。采用加、减、乘、除四则运算,允许中间运算存在小数,并且可以使用括号,但每张牌只能使用一次,尝试构造一种表达式,使其运算结果为24.
如
输入:3 3 7 7
输出:(((3)/(7))+(3))*(7) - 实现思路
遍历所有可能的组合(对四个运算符在三个位置所有排列方式,非全排列(四个字符,三个位置)),然后对运算符的全排列的每一种形式与四个数字串联起来构成一个表达式,对这个表达式通过不同加括号的方式(分治法求解)求取对应表达式的值是否为24。 - 概要代码
- 对运算符求其所有的排列方式(深度优先搜索-含有相同元素求排列-典型题),写法可参照之前本人的总结
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> permutes = new ArrayList<>();
List<Integer> permuteList = new ArrayList<>();
Arrays.sort(nums); // 排序
boolean[] hasVisited = new boolean[nums.length];
backtracking(permuteList, permutes, hasVisited, nums);
return permutes;
}
private void backtracking(List<Integer> permuteList, List<List<Integer>> permutes, boolean[] visited, final int[] nums) {
if (permuteList.size() == nums.length) {
permutes.add(new ArrayList<>(permuteList));
return;
}
for (int i = 0; i < visited.length; i++) {
if (i != 0 && nums[i] == nums[i - 1] && !visited[i - 1]) {
continue; // 防止重复
}
if (visited[i]){
continue;
}
visited[i] = true;
permuteList.add(nums[i]);
backtracking(permuteList, permutes, visited, nums);
permuteList.remove(permuteList.size() - 1);
visited[i] = false;
}
}
2)将所得运算符排列与对应的四个数字组合出对应的表达式(略)
3)对所有的表达式:每个表达式通过不同加括号的方式(分治法典型题)求出值判断结果是否为24.
public List<Integer> diffWaysToCompute(String input) {
List<Integer> ways = new ArrayList<>();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c == '+' || c == '-' || c == '*') {
List<Integer> left = diffWaysToCompute(input.substring(0, i));
List<Integer> right = diffWaysToCompute(input.substring(i + 1));
for (int l : left) {
for (int r : right) {
switch (c) {
case '+':
ways.add(l + r);
break;
case '-':
ways.add(l - r);
break;
case '*':
ways.add(l * r);
break;
}
}
}
}
}
if (ways.size() == 0) {
ways.add(Integer.valueOf(input));
}
return ways;
}
推荐阅读