2. 解題思路
- 注意:通常狀況下,反轉操做須要有兩個指針
- 遞歸思路
- 遞歸相似於棧操做的入棧和出棧,關鍵在於入棧哪些數據?
- 針對這道題目,因爲是反轉操做,因此須要入棧兩個指針,假定爲prev和cur兩個指針
- 爲了可以反轉,prev指針應該爲cur的next指針,只有這樣依次出棧的時候,prev指針纔是指向反轉鏈表過程當中的prev節點
- 迭代思路
- 採用兩個指針的頭插法反轉鏈表
3. 算法
3.1 遞歸算法
- 首先,須要肯定遞歸函數的功能,此處的遞歸函數功能是返回原鏈表進行反轉以後的頭節點
- 遞歸結束條件:原鏈表爲空或者原鏈表只有一個節點
3.2 迭代算法
- 建立一個啞節點用於向新鏈表的頭部插入節點
- 用prev和cur兩個指針進行反轉操做
4. 實現
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
遞歸算法
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == NULL || head->next == NULL) return head;
ListNode *new_prev = head->next; //存儲新構成的鏈表的最後一個節點
ListNode *new_head = reverseList(head->next); //反轉從下一個節點開始的鏈表
new_prev->next = head;
head->next = NULL;
return new_head;
}
};
迭代算法
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == NULL) return head;
ListNode dummy(-1);
dummy.next = head;
ListNode *head2 = &dummy;
ListNode *prev = head2->next;
ListNode *cur = prev->next;
while(cur != NULL){
prev->next = cur->next;
cur->next = head2->next;
head2->next = cur; //頭插法
cur = prev->next;
}
return dummy.next;
}
};