記錄學習的三種反轉連結串列
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()
區間反轉函式就好啦,這個上面已經寫過了。