题目地址:力扣
解法1:三指针法
要反转链表,那么从链表头结点开始,头结点的next要指向空,那么就需要一个后继节点来保存头结点的后一个节点。有后继节点那么也需要一个当前节点(用head也可以,但是为了清楚表明可以另外用一个当前节点)。考虑头结点的后一节点要指向头结点,因此还需要一个前置节点来保存之前的节点。
这种方法总共需要借助三个指针来实现,分别是记录当前节点,上一节点以及后一节点。
思路:只要后一节点不为空,那么
1、将后继节点指向当前节点的next,即保存当前节点的下一节点
2、将当前节点的next指向前置节点,即反转过程
3、将前置节点指向当前节点(当前节点变成了下一次操作的前置节点)
4、将当前节点指向后继节点,即两个节点指向相同
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode *prevNode = nullptr;
ListNode *currNode = head;
ListNode *nextNode = head;
while(nextNode != nullptr)
{
nextNode = currNode->next;
currNode->next = prevNode;
prevNode = currNode;
currNode = nextNode;
}
return prevNode;
}
};
解法2:头插法
思路也很简单,正向链表只需要用头插法就可以反转了,但是这就需要一个哨兵节点来用于头插,最后返回的也是哨兵节点的next
class Solution {
public:
ListNode* reverseList(ListNode* head) {
// 哨兵节点
ListNode sentry(0);
ListNode *nextNode = head;
// 下一节点非空就执行头插操作
while (nextNode != nullptr)
{
nextNode = head->next;
head->next = sentry.next;
sentry.next = head;
head = nextNode;
}
return sentry.next;
}
};
解法3:递归法
涉及到需要反转的,就可以想可以从后往前做,但是单链表不能找其头结点,所以只能是用递归的方式从后往前
class Solution {
public:
ListNode* reverseList(ListNode* head) {
// 只要当前节点为空或者当前节点的next为空,都返回当前节点
if (head == nullptr || head->next == nullptr)
return head;
// 都不为空,那么就递归将原链表的尾节点带出来,赋给newHead
ListNode *newHead = reverseList(head->next);
// 当前节点的后继节点的next指针指向当前节点
head->next->next = head;
// 反转后原链表头结点的next应该为空,因此每次都把head的next置为空
head->next = nullptr;
return newHead;
}
};
解法4:尾置递归法
思路:尾置递归和前面的递归有所不同,递归的返回不再是从递归的里面出来,而是进入下一层递归。这也就意味着链表是从前往后走的,那么改变next之前就需要存下next指向的地方,因此需要用一个新的节点来保存。同时这个递归函数应该接受两个参数,所以不能直接写在reverseList的里面。
class Solution {
public:
ListNode* reverse(ListNode* prev, ListNode *curr) {
ListNode *nextNode;
// 当前节点为空,说明到了prev正好指向链尾节点(新链头)
if (curr == nullptr)
return prev;
// 当前节点不空,就先存下当前节点的next,然后把当前节点的next指向prev
nextNode = curr->next;
curr->next = prev;
// 递归执行下一个节点
return reverse(curr, nextNode);
}
ListNode* reverseList(ListNode* head) {
return reverse(nullptr, head);
}
};
Accepted
- 28/28 cases passed (8 ms)
- Your runtime beats 48.56 % of cpp submissions
- Your memory usage beats 21.96 % of cpp submissions (8.2 MB)