反轉連結串列系列題練習遞迴

JerryWanG97發表於2024-06-26

記錄學習的三種反轉連結串列

leetcode206:反轉連結串列

    ListNode* reverseList(ListNode* head) {  
    }

思路:(僅遞迴)

  • 首先,明確函式定義。傳入連結串列頭節點,將連結串列反轉後,返回新的頭節點。
  • 接著,明確如何遞迴。比如本題就是傳入下一個節點即可。
    ListNode* newhead = reverseList(head->next);
  • 接著,明確操作。也就是說,拿到上一步返回的頭節點後該怎麼操作?很顯然,需要找到反轉後連結串列的尾節點tailNode,然後將tailNode->next = curNode(當前節點);
  • 最後,明確個例。個例就是遞迴終結的情況,不然一直遞迴。這個題的個例很明確,就是當連結串列有且僅有一個節點時,直接返回。if(head->next == nullptr) return head;
  • 最最後,明確邊界條件/特殊情況。本題只有一個 head==nullptr

leetcode92:反轉連結串列II

    ListNode* reverseBetween(ListNode* head, int left, int right) {
    }

思路(1):(區域性遞迴)

  • 首先,明確函式定義。傳入連結串列頭節點,左起、右止的節點個數,反轉後返回頭節點。
  • 接著,明確操作。把[left,right]區間內的節點用 遞迴方法 反轉,記錄左起的前一個節點pre,右止的後一個節點post,然後將
    pre->next->next = post;
    pre->next = newhead;
  • 明確個例。這個思路主要是儲存pre和post節點,[left,right]區間反轉的個例還是單個節點的情況。

思路(2):(整體遞迴)

  • 首先,明確函式定義。傳入連結串列頭節點,左起、右止的節點個數,反轉後返回頭節點。
  • 接著,明確怎麼遞迴。傳入下個幾點,左起數-1,右止數-1。
    ListNode* newhead = reverseBetween(head->next, left-1, right-1);
  • 接著,明確操作。同樣的問題,拿到上一步返回的頭節點該怎麼操作?只有一個操作,那就是是將當前節點的next指向newhead
    head->next = newhead;
  • 明確個例。本題個例和邊界特殊情況是一樣的。我是在處理完邊界條件後,才發現這原來是TM個例。
    if(left == 1){ }
    也就是從第一個node開始反轉。這裡需要改編反轉連結串列,以前是反轉整個list,也就是當head->next==nullptr的時候return,現在則是當head->next==someoneNode的時候return。

總結,這道題還是用我自己的思路1比較清晰。

leetcode25: K 個一組翻轉連結串列

    ListNode* reverseKGroup(ListNode* head, int k) {
    }

我的思路:
解構題目,K個一組反轉list,只需要寫個迴圈,然後每次都呼叫reverseBetween()區間反轉函式就好啦,這個上面已經寫過了。

相關文章