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.gitExamples: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
由於要輸出全部可能的狀況,一定是用深度優先搜索。問題在於如何將問題拆分紅屢次搜索。加減法很好處理,每當咱們截出一段數字時,將以前計算的結果加上或者減去這個數,就能夠將剩餘的數字字符串和新的計算結果代入下一次搜索中了,直到咱們的計算結果和目標同樣,就完成了一次搜索。然而,乘法如何處理呢?這裏咱們須要用一個變量記錄乘法當前累乘的值,直到累乘完了,遇到下一個加號或減號再將其算入計算結果中。這裏有兩種狀況:字符串
乘號以前是加號或減號,例如2+3*4
,咱們在2那裏算出來的結果,到3的時候會加上3,計算結果變爲5。在到4的時候,由於4以前咱們選擇的是乘號,這裏3就應該和4相乘,而不是和2相加,因此在計算結果時,要將5先減去剛纔加的3獲得2,而後再加上3乘以4,獲得2+12=14
,這樣14就是到4爲止時的計算結果。get
另一種狀況是乘號以前也是乘號,若是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
,當下一輪搜索是乘法時,prevNum
是prevNum
乘以currNum
。it
第一次搜索不添加運算符,只添加數字,就不會出現+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); } } } }