一、题目
题目链接:力扣
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
二、题解
1、思路
两种方法,没啥多说的!
🍍 递归;
🍍 非递归。
2、代码
// 递归
class Solution {
public:
ListNode* reverseList(ListNode* head) {
// 结束条件
if(head == NULL|| head->next == NULL)return head;// 如果链表为空或者只有一个结点,无需反转直接返回链表
ListNode* p = head->next;// 记录反转后链表的最后一个结点
// 反转除第一个元素(head指向的)之外的元素
ListNode* new_head = reverseList(head->next);
// 将原来链表的第一个结点放到最后
p->next = head;
// 最后一个元素指向NULL
head->next = NULL;
return new_head;
}
};
// 递归三要素
// 1.明确函数的功能:注意返回值
// 2.明确截止条件:一般在进入函数的时候判断
// 3.明确等价关系:一般在判断截止条件之后
// 非递归
class Solution {
public:
ListNode* reverseList(ListNode* head) {
//if(head == NULL|| head->next == NULL)return head;// 如果链表为空或者只有一个结点,无需反转直接返回链表
// 迭代的思想:后一个结点的指针指向前一个结点
// 注意:使用以下方法可使第一个结点(前面无结点)不需要特殊处理
ListNode* left = NULL;
ListNode* current = head;
ListNode* right = NULL;
// 注意:current是主线,left和right是两个附庸
// right和left都需要通过current进行更新
// 不要出现right = right->next的情况
while(current)
{
// 从右往左处理
right = current->next;// 暂存
current->next = left;// 改变指针指向
left = current;// 更新左侧
current = right;// 更新右侧
}
return left;
}
};
3、复杂度分析
🍍 递归:
时间复杂度:O(n);
空间复杂度:O(n)。
🍍 非递归:
时间复杂度:O(n);
空间复杂度:O(1)。
4、运行结果
🍍 递归:
🍍 非递归: