1.
第一种思路是采用递归调用的方式,通过递归获取最后一个结点和它前面的结点,让后面的结点指向前面的结点即head->next->next =head,这个是关键,看懂这一步代表已经没问题了。最后只需要让当前当前结点的next等于nullptr即可。p一直是指向递归后序列的头结点。所以操作head即可
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==nullptr || head->next ==nullptr) //递归出来的条件
return head;
ListNode *p=reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return p;
}
};
2.不适用递归的方式
思路是有三个结点需要定义
一个为前结点即一开为头结点之前即nullptr,但是用来之后用来记录头结点
一个为当前结点,这个当前结点最终要走向nullptr
一个结点为当前结点之后的那个点,最后也要是nullptr
所以最终返回的是前结点
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == nullptr || head->next ==nullptr)
return head;
ListNode *q = nullptr; //记录前一个结点
ListNode *p = head; //记录当前结点
while(p!=nullptr)
{
ListNode *w = p->next; //记录后一个结点
p->next = q; //让当前结点的next值等于上一个结点即q
q = p;//更新q结点,让它一直为头结点
p =w; //更新p的位置,让链表继续遍历
}
return q;
}
};