<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          ?LeetCode刷題實戰(zhàn)282:給表達式添加運算符

          共 5096字,需瀏覽 11分鐘

           ·

          2021-06-02 20:37

          算法的重要性,我就不多說了吧,想去大廠,就必須要經過基礎知識和業(yè)務邏輯面試+算法面試。所以,為了提高大家的算法能力,這個公眾號后續(xù)每天帶大家做一道算法題,題目就從LeetCode上面選 !

          今天和大家聊的問題叫做 給表達式添加運算符,我們先來看題面:
          https://leetcode-cn.com/problems/expression-add-operators/

          Given a string num that contains only digits and an integer target, return all possibilities to add the binary operators '+', '-', or '*' between the digits of num so that the resultant expression evaluates to the target value.

          給定一個僅包含數字 0-9 的字符串和一個目標值,在數字之間添加 二元 運算符(不是一元)+、- 或 * ,返回所有能夠得到目標值的表達式。

          示例


          示例 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
          輸出: []


          解題

          https://blog.csdn.net/RJ_theMag/article/details/108277129


          對于每個位置的兩個數之間,都有四種選擇:加、減、乘、不填符號(這樣兩個數就連在一起構成一個更大的數)。

          我們可以構造一個代數結構,使得不管下一個位置的數是什么,這個數后面填什么符號,我們都能記錄前面已經計算過的字符串的值。

          這個代數結構是a + b × c。a 是我們前面記錄過的字符串表達式的值,b是我們當前搜索到的數,c是b下一個位置的數。

          這樣,如果c后面的符號是+,則整個表達式的值可以用(a+b×c) + 1 × _ 來維護,a + b × c就是a變量的下一個值,也就是我們當前已經搜索到的字符串表達式的值,_是剩下的字符串的值。a更新為 a+b×c, b更新為1;

          同理,如果c后面的符號是-,則整個表達式的值可以用(a+b×c) + (-1) × _來維護。a更新為a+b×c, b更新為-1;
          如果c后面的符號是×,則整個表達式的值可以用a+(b×c)×_來維護。a還是a,b更新為b×c。
          如果c后面不填符號,我們直接更新c為一個更大的數: c = c × 10 + num[i] - ‘0’;表示兩個數連起來成為一個數。

          我們可以在字符串num的最后一位加上一個’+’,這樣有一個好處,當我們搜索到倒數第二個位置(加上‘+’之前的最后一個位置)時,我們只要看a的值是否是target就行了,如果a的值是target,則我們可以存下來當前的方案path(path是一個string類型的變量)。 這是因為如果最后一位是‘+’,則當前的a被更新為a + b * c(上面分析過了),如果遍歷完了原num字符串,這時的a就是最終的答案。


          typedef long long LL; // 中間結果可能爆int,需要long long來存
          class Solution {
          public:
              vector<string> res;
              string path; // path存放當前方案

              void dfs(string& num, int u, int len, LL a, LL b, LL target) { // u是當前搜索到了字符串num的位置,len是當前方案path的長度
                  if(u == num.size()) { // 如果搜索到了num的最后一個位置('+')
                      if(a == target) { // 這時a存放的就是當前方案下字符串num的值
                          res.push_back(path.substr(0, len - 1)); // len - 1是因為最后一位是'+'
                      }
                  } else {
                      LL c = 0; // c是我們當前要搜索的數
                      for(int i = u; i < num.size(); ++i) {
                          c = c * 10 + num[i] - '0';
                          path[len++] = num[i]; // 先把這個數加到方案path里
                          path[len] = '+'; // 搜索'+'的方案
                          dfs(num, i + 1, len + 1, a + b * c, 1, target); // a更新為a + b * c, b更新為1
                          if(i + 1 < num.size()) { // 如果沒到倒數第二位,說明還有插入'-'和'*'的方案
                              path[len] = '-';
                              dfs(num, i + 1, len + 1, a + b * c, -1, target); // a, b的更新之前已經分析過了
                              path[len] = '*';
                              dfs(num, i + 1, len + 1, a, b * c, target);
                          }
                          if(num[u] == '0') { // 不能有前導0
                              break;
                          }
                      }
                  }
              }

              vector<string> addOperators(string num, int target) {
                  path.resize(100); // 因為搜索的復雜度是指數級的,所以path長度不可能太長
                  dfs(num, 0, 0, 0, 1, target); // 最開始a是0,b是1,表示 0 + 1 * (整個num表達式可能的取值)
                  return res;
              }
          };


          好了,今天的文章就到這里,如果覺得有所收獲,請順手點個在看或者轉發(fā)吧,你們的支持是我最大的動力 。

          上期推文:

          LeetCode1-280題匯總,希望對你有點幫助!

          LeetCode刷題實戰(zhàn)281:鋸齒迭代器


          瀏覽 47
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  aⅴ中文字幕不卡在线无码 | 婷婷久久婷婷 | 99黄色 | 人人澡超碰碰 | 五月天草逼网址 |