Reverse a singly linked list.
Hint:
A linked list can be reversed either iteratively or recursively. Could you implement both?
Subscribe to see which companies asked this question
解法1:一個最簡單的辦法就是借助棧的后進先出功能,先掃描一遍鏈表保存每個節點的值,然后再從頭到尾遍歷,將棧中元素值一一賦給鏈表節點。時空復雜度都是O(n)。
/** * 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) { stack<int> elem; ListNode* curr = head; while(curr != NULL) { elem.push(curr->val); curr = curr->next; } curr = head; while(curr != NULL) { curr->val = elem.top(); curr = curr->next; elem.pop(); } return head; } };
解法2:可以做到in-place的反轉。鏈表反轉后,實際上只是中間節點的指針反轉,並且反轉后原來鏈表的頭結點的下一個節點應該為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* rHead = NULL; // 反轉后的頭節點 ListNode* curr = head; // 當前處理節點 ListNode* pTail = NULL; // 反轉后尾節點 while(curr != NULL) { ListNode* pNext = curr->next; if(pNext == NULL) rHead = curr; curr->next = pTail; pTail = curr; curr = pNext; } return rHead; } };
上面的是一個循環來進行反轉。遞歸的方式如下:
/** * 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* rHead = reverseList(head->next); // 反轉得到新鏈表的頭節點 head->next->next = head; // 當前節點的下一個節點的next指針反轉過來 head->next = NULL; // 設置新鏈表的尾節點 return rHead; } };