[LeetCode][C++] 用乾淨的方式寫 #19 Remove Nth Node From End of List
又是一個資料結構練習? 但仔細一看他希望我們做 one pass 就可以輸出答案。 我 OK,你先走 n 步 如果我們用左右兩個指標,讓右邊的指標先走 n 步,會發生什麼事? 我們就先模擬看看,當右邊的人一踩到 nullptr ,左邊的指標在哪? 假設 n=2 我們看到左邊的指標正好指著要刪除的 node,好像就做完了。 問題是,現在要怎麼刪除左邊的人? 單向的 linked list 一旦往後走就不能回頭了,我們想把 2 接到 4 現在就卡死動彈不得了。 我 OK,你先走 n + 1 步 既然我們想要把左右兩邊的指標再距離寬一點,那我們就會很直覺的想把 n + 1 再模擬看看: 但如果 n 剛好等於 linked list 長度,右邊先跑 n + 1 步的話左邊的人不就會超出範圍? 所以我們就用一個常見的技巧,創一個虛擬的 node,LeetCode 上叫做 dummy ,不過我覺得叫 root 比較好,比較有起始點的感覺。 當右邊指標撞到 nullptr 左邊指標的下一個人剛好就是要刪除的對象,這時候就不會有問題。 Boundary Cases 養成好習慣我們還是要稍微想一下比較容易出問題的邊界條件: 如果 n=1 會不會有問題? 不會 如果 n=size 會不會有問題? left 會在 root 的位置,刪除下一個人也不會有問題 好讀的 C++ 程式碼 我們想要讓維護的人一看就知道程式碼在做什麼,所以我的習慣就是用小小的 function 加上很好懂得名稱告訴別人我 function 在做什麼,而且一次只做一件事。 這樣 removeNthFromEnd 就會看起來很清爽: class Solution { public: ListNode *removeNthFromEnd(ListNode *head, int n) { ListNode root(0, head); ListNode *left = &root; ListNode *right = &root; right = moveNSteps(right, n + 1); while (right != nullptr) { left = moveNSteps(left, 1); right...