给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
方法一:双指针
一次遍历链表,遍历到的每一个节点,让当前节点的下一个节点指向它的上一个节点
class Solution {
public:
ListNode* reverseList(ListNode* head) {
//当head为空,或只含有head节点的话,我们直接返回head
if(head==nullptr||head->next==nullptr){
return head;
}
ListNode* preNode = nullptr; //preNode记录上一个节点
ListNode* nextNode = nullptr; //nextNode记录下一个节点
ListNode* curNode = head; //curNode记录当前节点
while(curNode != nullptr){
nextNode = curNode->next; //nextNode记录当前curNode的下一个节点
curNode->next=preNode; //令curNode的next指向其上一个节点preNode
preNode=curNode; //更新preNode位置
curNode=nextNode; //curNode位置
}
return preNode; //遍历结束之后preNode在原链表最后一个节点的尾部,即新获得的链表的头节点
}
};
方法二:递归
把递归分为三个部分以链表1->2->3->4->5举例
第一部分:函数的递归结束条件
第二部分:递归函数
第三部分:函数体
第一轮的时候,遍历到链表节点5的时候,递归条件不满足,直接返回,不会再执行第二和第三部分
/**
* 以链表1->2->3->4->5举例
* @param head
* @return
*/
public ListNode reverseList(ListNode head) {
if (head == nullptr || head.next == nullptr) {
/*
直到当前节点的下一个节点为空时返回当前节点
由于5没有下一个节点了,所以此处返回节点5
*/
return head;
}
//递归传入下一个节点,目的是为了到达最后一个节点
ListNode newHead = reverseList(head->next);
/*
第一轮出栈,head为5,head->next为空,返回5
第二轮出栈,head为4,head->next为5,执行head->next->next=head也就是5->next=4,
把当前节点的子节点的子节点指向当前节点
此时链表为1->2->3->4<->5,由于4与5互相指向,所以此处要断开4->next=null
此时链表为1->2->3->4<-5
返回节点5
第三轮出栈,head为3,head->next为4,执行head->next->next=head也就是4->next=3,
此时链表为1->2->3<->4<-5,由于3与4互相指向,所以此处要断开3->next=null
此时链表为1->2->3<-4<-5
返回节点5
第四轮出栈,head为2,head->next为3,执行head->next->next=head也就是3->next=2,
此时链表为1->2<->3<-4<-5,由于2与3互相指向,所以此处要断开2->next=null
此时链表为1->2<-3<-4<-5
返回节点5
第五轮出栈,head为1,head->next为2,执行head->next->next=head也就是2->next=1,
此时链表为1<->2<-3<-4<-5,由于1与2互相指向,所以此处要断开1->next=null
此时链表为1<-2<-3<-4<-5
返回节点5
出栈完成,最终头节点5->4->3-2->1
*/
head->next->next = head;
head->next = null;
return newHead;
}
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==nullptr||head->next==nullptr){
return head;
}
//递归的目的就是找到链表的最后一个节点,然后这个节点保存在newNode中
ListNode* newNode=reverseList(head->next);
//当得到链表中最后一个节点时执行一下代码
//令当前头节点的下一个节点,也就是本次递归的下一次递归操作的头节点的next指向本次递归的头节点
head->next->next=head;
//由于本次递归的头节点的next指向还不明确,所以赋空
head->next=nullptr;
//每次返回的是原链表的最后一个节点,即newNode中记录的值
return newNode;
}
};