先贴题目
代码随想录讲了两种方法,双指针和递归。下面依次介绍
- 双指针
- 用cur指向起始节点,用pre定义一个空节点作翻转之后的尾结点,翻转的过程就是cur往后遍历,pre跟着cur落后一个下标遍历,一直将cur的next指向pre就完成了反向。这里面就有两个问题,第一个是cur何时停下,按照前面的逻辑,当cur完成一次指向操作的时候会到达后一个位置,因此当完成尾部节点的时候cur会指向NULL,所以这里用cur != NULL即可;第二个就是单向链表的节点要访问只能由前面的节点来找到该访问的节点,把cur的next指向pre就会丢失后面的节点,因此要用一个指针来存储cur的下一个节点位置
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* cur = head;
ListNode* pre = NULL;
ListNode* temp;
while(cur != NULL){
temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}
};
- 递归方法
递归的逻辑和双指针是一样的,指针一直往后遍历的同时next指向前面的节点,不同的是双指针的temp要用作恢复cur,递归直接把temp当做cur继续迭代下去。
class Solution {
public:
ListNode* reverse(ListNode* cur,ListNode* pre){
if(cur ==NULL) {
return pre;
}
ListNode* temp;
temp = cur->next;
cur->next = pre;
return reverse(temp,cur);
}
ListNode* reverseList(ListNode* head) {
return reverse(head,NULL);
}
};