【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)

其实回溯法的原理就是利用DFS实现的,本题递归的结束条件就是动态数组只剩一个元素且元素==24.

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);
    }
}
原文地址:https://www.cnblogs.com/XDU-Lakers/p/13547432.html