[Leetcode] Expression Add Operators 添加運算符

Expression Add Operators

Given a string that contains only digits 0-9 and a target value, return all possibilities to add binary operators (not unary) +, -, or * between the digits so they evaluate to the target value.git

Examples:lua

"123", 6 -> ["1+2+3", "1*2*3"] 
"232", 8 -> ["2*3+2", "2+3*2"]
"105", 5 -> ["1*0+5","10-5"]
"00", 0 -> ["0+0", "0-0", "0*0"]
"3456237490", 9191 -> []

深度優先搜索

複雜度

時間 O(N^2) 空間 O(N)code

思路

由於要輸出全部可能的狀況,一定是用深度優先搜索。問題在於如何將問題拆分紅屢次搜索。加減法很好處理,每當咱們截出一段數字時,將以前計算的結果加上或者減去這個數,就能夠將剩餘的數字字符串和新的計算結果代入下一次搜索中了,直到咱們的計算結果和目標同樣,就完成了一次搜索。然而,乘法如何處理呢?這裏咱們須要用一個變量記錄乘法當前累乘的值,直到累乘完了,遇到下一個加號或減號再將其算入計算結果中。這裏有兩種狀況:字符串

  1. 乘號以前是加號或減號,例如2+3*4,咱們在2那裏算出來的結果,到3的時候會加上3,計算結果變爲5。在到4的時候,由於4以前咱們選擇的是乘號,這裏3就應該和4相乘,而不是和2相加,因此在計算結果時,要將5先減去剛纔加的3獲得2,而後再加上3乘以4,獲得2+12=14,這樣14就是到4爲止時的計算結果。get

  2. 另一種狀況是乘號以前也是乘號,若是2+3*4*5,這裏咱們到4爲止計算的結果是14了,而後咱們到5的時候又是乘號,這時候咱們要把剛纔加的3*4給去掉,而後再加上3*4*5,也就是14-3*4+3*4*5=62。這樣5的計算結果就是62。string

由於要解決上述幾種狀況,咱們須要這麼幾個變量,一個是記錄上次的計算結果currRes,一個是記錄上次被加或者被減的數prevNum,一個是當前準備處理的數currNum。當下一輪搜索是加減法時,prevNum就是簡單換成currNum,當下一輪搜索是乘法時,prevNumprevNum乘以currNumit

注意

  • 第一次搜索不添加運算符,只添加數字,就不會出現+1+2這種表達式了。io

  • 咱們截出的數字不能包含0001這種前面有0的數字,可是一個0是能夠的。這裏一旦截出的數字前導爲0,就能夠return了,由於說明前面就截的不對,從這以後都是開始爲0的,後面也不可能了。class

代碼

public class Solution {
    
    List<String> res;
    
    public List<String> addOperators(String num, int target) {
        helper(num, target, "", 0, 0);
        return res;
    }
    
    private void helper(String num, int target, String tmp, long currRes, long prevNum){
        // 若是計算結果等於目標值,且全部數都用完了,則是有效結果
        if(currRes == target && num.length() == 0){
            String exp = new String(tmp);
            res.add(exp);
            return;
        }
        // 搜索全部可能的拆分狀況
        for(int i = 1; i <= num.length(); i++){
            String currStr = num.substring(0, i);
            // 對於前導爲0的數予以排除
            if(currStr.length() > 1 && currStr.charAt(0) == '0'){
                // 這裏是return不是continue
                return;
            }
            // 獲得當前截出的數
            long currNum = Long.parseLong(currStr);
            // 去掉當前的數,獲得下一輪搜索用的字符串
            String next = num.substring(i);
            // 若是不是第一個字母時,能夠加運算符,不然只加數字
            if(tmp.length() != 0){
                // 乘法
                helper(next, target, tmp+"*"+currNum, (currRes - prevNum) + prevNum * currNum, prevNum * currNum);
                // 加法
                helper(next, target, tmp+"+"+currNum, currRes + currNum, currNum);
                // 減法
                helper(next, target, tmp+"-"+currNum, currRes - currNum, -currNum); 
            } else {
                // 第一個數
                helper(next, target, currStr, currNum, currNum);
            }

        }
    }
}
相關文章
相關標籤/搜索