1. 程式人生 > >[LeetCode] 679. 24 Game(回溯法)

[LeetCode] 679. 24 Game(回溯法)

desc ann 兩個 java lan sof vision res unary

傳送門

Description

You have 4 cards each containing a number from 1 to 9. You need to judge whether they could operated through *, /, +, -, (, )to get the value of 24.

Example 1:
Input: [4, 1, 8, 7]
Output: True
Explanation: (8-4) * (7-1) = 24
Example 2:
Input: [1, 2, 1, 2]
Output: False

Note:

  1. The division operator / represents real division, not integer division. For example, 4 / (1 - 2/3) = 12.
  2. Every operation done is between two numbers. In particular, we cannot use - as a unary operator. For example, with [1, 1, 1, 1] as input, the expression -1 -1 -1 -1 is not allowed.
  3. You cannot concatenate numbers together. For example, if the input is [1, 2, 1, 2], we cannot write this as 12 + 12.

思路

題意:給定四張標有數字(1-9)的卡片,問通過加減乘除和小括號組成的表達式的結果能否等於24。

題解:考慮窮舉法的話,四個數字共有4!種排列方法,4個數字中間加入符號共有4x4x4種方法,最後考慮小括號,小括號的放法共有(A(B(CD))、(A((BC)D)、((AB)(CD))、((A(BC))D)、(((AB)C)D)五種,那麽種類最多有4!x4^3x5 = 7680種。

考慮回溯法,首先我們從集合A = {1 、2、3、4}中任意取出兩個數,如取1、2,那麽A = A - {1、2},對取出來的兩個數字分別進行不同的四則運算,1 + 2、1 - 2……,將結果加入A中,有{3、3、4}、{-1,3,4}等,通過這種方法,將四個數降為三個數,然後降為兩個數……

Java

class Solution {
    boolean res = false;
    final double esp = 1e-4;
    public boolean judgePoint24(int[] nums) {
        List<Double>list = new ArrayList<Double>();
        for (int val:nums)  list.add((double)val);
        solver(list);
        return res;
    }

    void solver(List<Double> array){
        if (res)    return;
        if (array.size() == 1 && Math.abs(array.get(0) - 24.0) <= esp){
            res = true;
            return;
        }

        for (int i = 0;i < array.size();i++){
            for (int j = 0;j < i;j++){
                List<Double>list = new ArrayList<Double>();
                Double p1 = array.get(i),p2 = array.get(j);
                list.addAll(Arrays.asList(p1+p2,p1-p2,p2-p1,p1*p2));
                
                //除數是否為0
                if (Math.abs(p1) > esp){
                    list.add(p2/p1);
                }
                if (Math.abs(p2) > esp){
                    list.add(p1/p2);
                }

                array.remove(i);
                array.remove(j);

                for (Double val:list){
                    array.add(val);
                    solver(array);
                    array.remove(val);
                }

                array.add(j,p2);
                array.add(i,p1);

            }
        }
    }
}

  

[LeetCode] 679. 24 Game(回溯法)