<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>

          分享一個(gè)小技巧,提高刷題幸福感

          共 4119字,需瀏覽 9分鐘

           ·

          2021-04-03 23:12

          相信每個(gè)人都有過被代碼的小 bug 搞得心態(tài)爆炸的經(jīng)歷,本文分享一個(gè)我最常用的簡單技巧,可以大幅提升刷題的幸福感。

          在這之前,首先回答一個(gè)問題,刷力扣題是直接在網(wǎng)頁上刷比較好還是在本地 IDE 上刷比較好?

          如果是牛客網(wǎng)筆試那種自己處理輸入輸出的判題形式,一定要在 IDE 上寫,這個(gè)沒啥說的,像力扣這種判題形式,我個(gè)人偏好直接在網(wǎng)頁上刷,原因有二:

          1、方便

          因?yàn)榱塾械臄?shù)據(jù)結(jié)構(gòu)是自定的,比如說 TreeNodeListNode 這種,在本地你還得把這個(gè)類 copy 過去。

          而且在 IDE 上沒辦法測試,寫完代碼之后還得粘貼到網(wǎng)頁上跑測試數(shù)據(jù),那還不如直接網(wǎng)頁上寫呢。

          算法又不是工程代碼,量都比較小,IDE 的自動(dòng)補(bǔ)全帶來的收益基本可以忽略不計(jì)。

          2、實(shí)用

          到時(shí)候面試的時(shí)候,面試官給你出的算法題大都是希望你直接在網(wǎng)頁上完成的,最好是邊寫邊講你的思路。

          如果平時(shí)練習(xí)的時(shí)候就習(xí)慣沒有 IDE 的自動(dòng)補(bǔ)全,習(xí)慣手寫代碼大腦編譯,到時(shí)候面試的時(shí)候?qū)懘a就能更快更從容。

          之前我面快手的時(shí)候,有個(gè)面試官讓我 實(shí)現(xiàn) LRU 算法,我直接把雙鏈表的實(shí)現(xiàn)、哈希鏈表的實(shí)現(xiàn),在網(wǎng)頁上全寫出來了,而且一次無 bug 跑通,可以看到面試官驚訝的表情??

          我秋招能當(dāng) offer 收割機(jī),很大程度上就是因?yàn)槭謱懰惴ㄟ@一關(guān)超出面試官的預(yù)期,其實(shí)都是因?yàn)橹霸诰W(wǎng)頁上刷題練出來的。

          接下來分享我覺得最常實(shí)用的干貨技巧。

          如何給算法 debug

          代碼的錯(cuò)誤時(shí)無法避免的,有時(shí)候可能整個(gè)思路都錯(cuò)了,有時(shí)候可能是某些細(xì)節(jié)問題,比如 ij 寫反了,這種問題怎么排查?

          我想一般的算法問題肯定不難排查,肉眼檢查應(yīng)該都沒啥問題,再不濟(jì) print 打印一些關(guān)鍵變量的值,總能發(fā)現(xiàn)問題。

          比較讓人頭疼的的應(yīng)該是遞歸算法的問題排查

          如果沒有一定的經(jīng)驗(yàn),函數(shù)遞歸的過程很難被正確理解,所以這里就重點(diǎn)講講如何高效 debug 遞歸算法。

          有的讀者可能會(huì)說,把算法 copy 到 IDE 里面,然后打斷點(diǎn)一步步跟著走不就行了嗎?

          這個(gè)方法肯定是可以的,但是之前的文章多次說過,遞歸函數(shù)最好從一個(gè)全局的角度理解,而不要跳進(jìn)具體的細(xì)節(jié)。

          如果你對遞歸還不夠熟悉,沒有一個(gè)全局的視角,這種一步步打斷點(diǎn)的方式也容易把人繞進(jìn)去。

          我的建議是直接在遞歸函數(shù)內(nèi)部打印關(guān)鍵值,配合縮進(jìn),直觀地觀察遞歸函數(shù)執(zhí)行情況

          最能提升我們 debug 效率的是縮進(jìn),除了解法函數(shù),我們新定義一個(gè)函數(shù) printIndent 和一個(gè)全局變量 count

          // 全局變量,記錄遞歸函數(shù)的遞歸層數(shù)
          int count = 0;

          // 輸入 n,打印 n 個(gè) tab 縮進(jìn)
          void printIndent(int n) {
              for (int i = 0; i < n; i++) {
                  printf("   ");
              }
          }

          接下來,套路來了:

          在遞歸函數(shù)的開頭,調(diào)用 printIndent(count++) 并打印關(guān)鍵變量;然后在所有 return 語句之前調(diào)用 printIndent(--count) 并打印返回值

          舉個(gè)具體的例子,比如說上篇文章 練琴時(shí)悟出的一個(gè)動(dòng)態(tài)規(guī)劃算法 中實(shí)現(xiàn)了一個(gè)遞歸的 dp 函數(shù),大致的結(jié)構(gòu)如下:

          int dp(string& ring, int i, string& key, int j) {
              /* base case */
              if (j == key.size()) {
                  return 0;
              }

              /* 狀態(tài)轉(zhuǎn)移 */
              int res = INT_MAX;
              for (int k : charToIndex[key[j]]) {
                  res = min(res, dp(ring, j, key, i + 1));
              }

              return res;
          }

          這個(gè)遞歸的 dp 函數(shù)在我進(jìn)行了 debug 之后,變成了這樣:

          int count = 0;
          void printIndent(int n) {
              for (int i = 0; i < n; i++) {
                  printf("   ");
              }
          }

          int dp(string& ring, int i, string& key, int j) {
              // printIndent(count++);
              // printf("i = %d, j = %d\n", i, j);

              if (j == key.size()) {
                  // printIndent(--count);
                  // printf("return 0\n");
                  return 0;
              }

              int res = INT_MAX;
              for (int k : charToIndex[key[j]]) {
                  res = min(res, dp(ring, j, key, i + 1));
              }

              // printIndent(--count);
              // printf("return %d\n", res);
              return res;
          }

          就是在函數(shù)開頭和所有 return 語句對應(yīng)的地方加上一些打印代碼

          如果去掉注釋,執(zhí)行一個(gè)測試用例,輸出如下:

          這樣,我們通過對比對應(yīng)的縮進(jìn)就能知道每次遞歸時(shí)輸入的關(guān)鍵參數(shù) i, j 的值,以及每次遞歸調(diào)用返回的結(jié)果是多少。

          最重要的是,這樣可以比較直觀地看出遞歸過程,你有沒有發(fā)現(xiàn)這就是一棵遞歸樹

          前文 動(dòng)態(tài)規(guī)劃套路詳解 說過,理解遞歸函數(shù)最重要的就是畫出遞歸樹,這樣打印一下,連遞歸樹都不用自己畫了,而且還能清晰地看出每次遞歸的返回值。

          可以說,這是對刷題「幸福感」提升最大的一個(gè)小技巧,比 IDE 打斷點(diǎn)要高效

          好了,本文分享就到這里,馬上快過年了,估計(jì)大家都無心學(xué)習(xí)了,不過刷題還是要堅(jiān)持的,這就叫彎道超車,順便實(shí)踐一下這個(gè)技巧。

          如果本文對你有幫助,點(diǎn)個(gè)在看,就會(huì)被推薦更多相似文章。

          推薦閱讀:

          完全整理 | 365篇高質(zhì)技術(shù)文章目錄整理

          算法之美 : 棧和隊(duì)列

          主宰這個(gè)世界的10大算法

          徹底理解cookie、session、token

          淺談什么是遞歸算法

          專注服務(wù)器后臺(tái)技術(shù)棧知識(shí)總結(jié)分享

          歡迎關(guān)注交流共同進(jìn)步

          瀏覽 32
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  五月婷婷综合色 | 国产高清第一页 | 一区 激情 自拍 豆花 | 成人网站在线观看免费 | 久久3级片 |