問題描述:
反轉一個單鏈表。
示例:
輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL
進階:
你可以迭代或遞歸地反轉鏈表。你能否用兩種方法解決這道題?
解法一:
掃描一遍,每掃描到一個節點,就將這個節點與下個節點的方向顛倒一下,掃描一遍之後就實現了反轉。
代碼如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode *current = head;//當前的節點
ListNode *temp_next;
ListNode *preview = NULL;//前邊的節點
while(current != NULL){
temp_next = current->next;
current->next=preview;
preview=current;
current=temp_next;
}
return preview;
}
};
自己畫的原理圖如下(太難看了,自己都看不下去了):
解法二:
把上面的代碼修改成使用遞歸的方法。
可以加一個“啞結點”指向頭結點。
代碼如下:
ListNode* reverseList(ListNode* head) {
if(!head){
return nullptr;
}
return reverse(head, head, head->next);
}
ListNode* reverse(ListNode* head, ListNode* first, ListNode* target){
if(!target){
return head;
}
first->next = target->next;
ListNode* temp = target->next;
target->next = head;
return reverse(target, first, temp);
}
這個遞歸代碼參考大佬的:
作者:sunshy
鏈接:https://leetcode-cn.com/problems/two-sum/solution/die-dai-di-gui-jie-fa-by-sunshy/
解法三:
力扣官方的遞歸方法:
代碼如下:
/**
* Definition for singly-linked list.
* 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 *p = reverseList(head->next);
head->next ->next = head;
head->next = NULL;
return p;
}
};