給表示式新增運算子
阿新 • • 發佈:2021-10-21
給表示式新增運算子
給定一個僅包含數字0-9
的字串num
和一個目標值整數target
,在num
的數字之間新增二元運算子(不是一元)+
、-
或*
,返回所有能夠得到目標值的表示式。
示例 1:
輸入: num =
"123", target = 6
輸出: ["1+2+3", "1*2*3"]
示例2:
輸入: num =
"232", target = 8
輸出: ["2*3+2", "2+3*2"]
示例 3:
輸入: num =
"105", target = 5
輸出: ["1*0+5","10-5"]
示例4:
輸入: num =
"00", target = 0
輸出: ["0+0", "0-0", "0*0"]
示例 5:
輸入: num =
"3456237490", target = 9191
輸出: []
難點:
①:有多位數,這些數字可不都是光有個位數。
②:0 的特殊性。它可以作為一個數字出現,但不能是多位數的首位。
③:在中間新增運算子,也就是說在加入第一個數的時候是不新增運算子的,運算子數量至少比數字數量少一。
解決方法:
①:每次更新 a 的值;
for(int i = index; i < n; i++){ a = a * 10 + Num[i] - '0'; }
②:當前位置是首位 或者 首位的那個數字不是 0。
i == index || Num[index] != '0'
③:如果當前位置是首位的時候,只能進入唯一 的 dfs 入口。
if(index == 0){ dfs(i + 1, s + to_string(a), a, a); }else{ dfs(i + 1, s + '+' + to_string(a), sum + a, a); …… }
思路:
設定字串 s 儲存答案,以及變長陣列 ans 儲存每個字串 s 。
設定變數 a,記錄每次要放入 s 的數字(可能是多位數).利用 dfs 搜尋,把每一步放入 s ,並記錄每次的 cnt ,和總和 sum 。
dfs 詳解:
在已經找到要放入的數之後,就是 ' + ', ' - ', ' * ', 這三種情況的選擇問題了,按個試就OK。。
第一種,中間是+,則sum加上第ii段數字。
第二種,中間是−,則sum減去第ii段數字。
第三種,中間是×,則sum減去上一段連續乘的值(因此我們需要在遞迴的時候記錄上一段的值,對於第i段數字,即記錄第i-1的數字是多少),再加上 第i-1段數字×第i段數字。
class Solution { public: vector<string > ans; string Num; int Target, n; void dfs(int index, string s,long long sum, long long cnt){ long long a = 0; if(index == n){ if(sum == Target) ans.push_back(s); return; } for(int i = index; i < n && (i == index || Num[index] != '0'); i++){ a = a * 10 + Num[i] - '0'; if(index == 0){ dfs(i + 1, s + to_string(a), a, a); }else{ dfs(i + 1, s + '+' + to_string(a), sum + a, a); dfs(i + 1, s + '-' + to_string(a), sum - a, -a); dfs(i + 1, s + '*' + to_string(a), sum - cnt + cnt * a,cnt * a); } } } vector<string> addOperators(string num, int target) { Num = num; Target = target; n = num.size(); dfs(0, "", 0, 0); return ans; } };