题目:
题解1:
在一刷时采用双指针(加一个临时指针)的方法,不耗费额外空间。
时间复杂度:O(n)
空间复杂度:O(1)
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == NULL)return NULL;
ListNode* pre;
ListNode* cur;
pre = head;
cur = NULL;
while(pre != NULL)
{
ListNode* tmp = pre->next;//临时指针,保存pre的下一个节点地址
pre->next = cur;
cur = pre;
pre = tmp;
}
return cur;
}
};
题解2:
二刷学习的方法,很简洁,思路也很骚,学会递归还是有点东西的。
- 使用递归函数,一直递归到链表的最后一个结点,该结点就是反转后的头结点,记作 newhead 。
- 此后,每次函数在返回的过程中,让当前结点的下一个结点的
指针指向当前节点。
- 同时让当前结点的
指针指向NULL,从而实现从链表尾部开始的局部反转。
- 当递归函数全部出栈后,链表反转完成。
递归的本质就是栈,将节点递进到结尾,回归时将节点方向反转。
转作者huwt的动画,链接如下。
链接:https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/solution/fan-zhuan-lian-biao-yi-dong-de-shuang-zhi-zhen-jia/
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == NULL || head->next == NULL) {
return head;//当head为空 或者 节点到达尾结点时,返回head为新首节点
}
ListNode* ret = reverseList(head->next);//递进
//从尾部开始一步步改变节点方向
head->next->next = head;
head->next = NULL;
return ret;//返回的始终是head节点
}
};