AcWing 35 反轉鏈表
題目
定義一個函數,輸入一個鏈表的頭結點,反轉該鏈表並輸出反轉後鏈表的頭結點。
思考題:
- 請同時實現迭代版本和遞歸版本。
樣例
輸入:1->2->3->4->5->NULL
輸出:5->4->3->2->1->NULL
思路
迭代版本
這道題使用迭代的思想很容易思考,我們只需要準備三個指針,分別是上一個節點prev
、當前節點curr
和curr
的下一個節點node
通過遍歷整個鏈表,沒到一個節點,我們先保存curr.next
給node
,再將curr.next
賦給prev
,也就改變了curr
的指向,隨後我們把curr
和prev
都後移一位即可(在原來的順序上,因爲我們已經保留了node
),當curr == null
時,說明鏈表已經到結尾了,我們返回prev
即可
遞歸版本
遞歸版本如何思考呢,我們只需要思考一種情況,由於是遞歸實現,當遞歸到head
節點時,我們需要遞歸函數返回的結果是一個從head.next
開始已經被反轉的鏈表,所以我們只需要將head
接到鏈表的結尾,並將head.next
指空即可
代碼
c++ 迭代
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode *prev = NULL, *cur = head;
while (cur) {
auto node = cur->next;
cur->next = prev;
prev = cur;
cur = node;
}
return prev;
}
};
c++ 遞歸
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (!head || !head->next)
return head;
auto tail = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return tail;
}
};
java 迭代
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode node = curr.next;
curr.next = prev;
prev = curr;
curr = node;
}
return prev;
}
}
java 遞歸
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null)
return head;
ListNode tail = head.next;
ListNode node = reverseList(head.next);
tail.next = head;
head.next = null;
return node;
}
}