LeetCode hot 100—反转链表

题目

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例

示例 1:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]

分析

迭代法

逐个改变节点的指向,非常适合处理大规模链表。

时间复杂度:O(n)

空间复杂度:O(1)

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* prev = nullptr; // 初始化前驱指针为 null
        ListNode* curr = head;    // 当前指针指向头节点
        while (curr) {
            ListNode* nextTemp = curr->next; // 暂存当前节点的下一个节点
            curr->next = prev;               // 将当前节点的 next 指针反转,指向前一个节点
            prev = curr;                     // 将 prev 移动到当前节点
            curr = nextTemp;                 // 将 curr 移动到下一个节点(原链表的下一个节点)
        }
        return prev; // prev 成为新的头节点
    }
};

递归法

假设链表从第二个节点开始已经反转好了,然后将第一个节点接到已反转链表的尾部。

递归过程举例

假设链表为:1 -> 2 -> 3 -> nullptr

  • 初始调用:reverseList(1)

    head 为节点 1,不满足终止条件,递归调用 reverseList(2)
  • 第二次调用:reverseList(2)

    head 为节点 2,不满足终止条件,递归调用 reverseList(3)
  • 第三次调用:reverseList(3)

    head 为节点 3,满足 head->next == nullptr,返回节点 3
  • 回到第二次调用:

    newHead 为节点 3。将 2->next->next(即 3->next)设置为节点 2,实现链接 3 -> 2。设置 2->next = nullptr,返回 newHead(节点 3)。
  • 回到第一次调用:

    newHead 仍为节点 3。将 1->next->next(即 2->next)设置为节点 1,实现链接 2 -> 1。设置 1->next = nullptr,返回 newHead(节点 3)。

最终链表反转为:3 -> 2 -> 1 -> nullptr

递归方法代码更简洁,但 递归深度大时可能导致栈溢出

时间复杂度:O(n)

空间复杂度:O(n)

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if (!head || !head->next) return head; // 递归终止条件
        ListNode* newHead = reverseList(head->next); // 反转剩余链表
        head->next->next = head; // 让当前节点的下一个节点指向自己
        head->next = nullptr; // 断开原来的连接
        return newHead; // 返回新的头节点
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rigidwill666

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值