[LeetCode] Expression Add Operators 表示式增加操作符
Given a string that contains only digits 0-9
and a target value, return all possibilities to add operators +
, -
, or *
between the digits so they evaluate to the target value.
Examples:
"123", 6 -> ["1+2+3", "1*2*3"] "232", 8 -> ["2*3+2", "2+3*2"] "00", 0 -> ["0+0", "0-0", "0*0"] "3456237490", 9191 -> []
Credits:
Special thanks to @davidtan1890 for adding this problem and creating all test cases.
這道題給了我們一個只由數字組成的字串,讓我們再其中新增+,-或*號來形成一個表示式,該表示式的計算和為給定了target值,讓我們找出所有符合要求的表示式來。題目中給的幾個例子其實並不好,很容易讓人誤以為是必須拆成個位數字,其實不是的,比如"123", 15能返回"12+3",說明連著的數字也可以。如果非要在過往的題中找一道相似的題,我覺得跟Combination Sum II 組合之和之二很類似。不過這道題要更復雜麻煩一些。還是用遞迴來解題,我們需要兩個變數diff和curNum,一個用來記錄將要變化的值,另一個是當前運算後的值,而且它們都需要用long long型的,因為字串轉為int型很容易溢位,所以我們用長整型。對於加和減,diff就是即將要加上的數和即將要減去的數的負值,而對於乘來說稍有些複雜,此時的diff應該是上一次的變化的diff乘以即將要乘上的數,有點不好理解,那我們來舉個例子,比如2+3*2,即將要運算到乘以2的時候,上次迴圈的curNum = 5, diff = 3, 而如果我們要算這個乘2的時候,新的變化值diff應為3*2=6,而我們要把之前+3操作的結果去掉,再加上新的diff,即(5-3)+6=8,即為新表示式2+3*2的值,有點難理解,大家自己一步一步推算吧。
還有一點需要注意的是,如果輸入為"000",0的話,容易出現以下的錯誤:
Wrong:["0+0+0","0+0-0","0+0*0","0-0+0","0-0-0","0-0*0","0*0+0","0*0-0","0*0*0","0+00","0-00","0*00","00+0","00-0",
"00*0","000"]
Correct:["0*0*0","0*0+0","0*0-0","0+0*0","0+0+0","0+0-0","0-0*0","0-0+0","0-0-0"]
我們可以看到錯誤的結果中有0開頭的字串出現,明顯這不是數字,所以我們要去掉這些情況,過濾方法也很簡單,我們只要判斷長度大於1且首字元是‘0’的字串,將其濾去即可,參見程式碼如下:
class Solution { public: vector<string> addOperators(string num, int target) { vector<string> res; addOperatorsDFS(num, target, 0, 0, "", res); return res; } void addOperatorsDFS(string num, int target, long long diff, long long curNum, string out, vector<string> &res) { if (num.size() == 0 && curNum == target) { res.push_back(out); } for (int i = 1; i <= num.size(); ++i) { string cur = num.substr(0, i); if (cur.size() > 1 && cur[0] == '0') return; string next = num.substr(i); if (out.size() > 0) { addOperatorsDFS(next, target, stoll(cur), curNum + stoll(cur), out + "+" + cur, res); addOperatorsDFS(next, target, -stoll(cur), curNum - stoll(cur), out + "-" + cur, res); addOperatorsDFS(next, target, diff * stoll(cur), (curNum - diff) + diff * stoll(cur), out + "*" + cur, res); } else { addOperatorsDFS(next, target, stoll(cur), stoll(cur), cur, res); } } } };
參考資料: