题目:
Leetcode上只有Reverse Linked List II,但是最朴素的反转链表还是很常用的。
思路一:非递归,in-place.
假设现在链表反转到了3->2->1->4->5,下一个需要反转4. 那么只需要将1指向5,4指向3,新的head赋值给4即可。
class Solution {
public:
ListNode* reverse_linked_list(ListNode *head) {
if (head == nullptr) return head;
ListNode dummy(0);
dummy.next = head;
ListNode* runner = head->next;
ListNode* tail = head;
while (runner != nullptr) {
ListNode* next_runner = runner->next;
runner->next = dummy.next;
dummy.next = runner;
tail->next = next_runner;
runner = next_runner;
}
return dummy.next;
}
};
思路二:非递归,previous指针。
只需要一个previous指针记录上一个node,那么将当前node指向上一个node即可。
class Solution {
public:
ListNode* reverse_linked_list(ListNode *head) {
ListNode* previous = nullptr;
ListNode* runner = head;
while (runner != nullptr) {
ListNode* next_runner = runner->next;
runner->next = previous;
previous = runner;
runner = next_runner;
}
return previous;
}
};
思路三:非递归,stack实现。将所有node依次push到stack中,再一一弹出。空间复杂度为O(n),不推荐。
思路四:递归。
递归的过程实际上就是将node一一入栈的过程。在调用递归函数的过程中将链表断开,然后从后往前连接。返回值是新head的地址。
class Solution {
public:
ListNode *removeNthFromEnd(ListNode *head, int n) {
if (head == nullptr || head->next == nullptr) return head;
ListNode* next_node = head->next;
head->next = nullptr;
ListNode* new_head = reverse_linked_list(next_node);
next_node->next = head;
return new_head;
}
};