链表OJ - 2(反转链表)

发布于:2024-04-18 ⋅ 阅读:(55) ⋅ 点赞:(0)

题目描述(来源)

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

        如下为图解

 思路

思路一(双指针)

        从前向后遍历链表,然后把每个结点的 next 指向前一个结点就好。
        具体实现中,首先需要两个指针,一个 cur 指针在遍历到每个结点进行操作,一个 prev 指针指向 cur 的前一个结点。其次,由于 cur->next 指向 prev,导致原来的 cur 的下一个结点失去引用,所以还需要一个指针 temp 用来保存后一个结点。

struct ListNode* reverseList(struct ListNode* head)
{
    // 初始化两个指针,cur 用于遍历链表,初始时指向头节点
    struct ListNode* cur = head;
    
    // 初始化一个指针 prev 用于暂存每个节点的前一个节点,初始时 prev 为 NULL
    struct ListNode* prev = NULL;

    // 当 cur 不为空时,执行循环
    while (cur) 
    {
        // 临时存储 cur 节点的下一个节点(即将被 cur 节点覆盖的下一个节点的地址)
        struct ListNode* temp = cur->next;

        // 修改 cur 节点的 next 指针,使其指向 prev 节点,即完成了一次节点间的翻转连接
        cur->next = prev;

        // prev 和 cur 同时向前移动一步,prev 移动到 cur 的位置,cur 移动到下一个节点的位置
        prev = cur;
        cur = temp;
    }

    // 当循环结束时,prev 指针指向了原链表的新头部,因此返回 prev 作为翻转后链表的新头节点
    return prev;
}

思路二(递归法)

        递归法和双指针法是一样的逻辑,同样是当 curr 为空的时候循环结束,不断将 curr 指向 pre 的过程。

struct ListNode* reverseList(struct ListNode* head) 
{
    // 基线条件:如果头结点为空或者只有一个结点,无需反转,直接返回头结点
    if (head == NULL || head->next == NULL) 
    {
        return head;
    }

    // 递归调用,将后续部分链表反转,并获取反转后的尾结点
    struct ListNode* newTail = reverseList(head->next);

    // 将尾结点的next指针指向当前头结点,完成局部反转
    head->next->next = head;

    // 更新当前头结点的next指针,使其指向NULL,成为新的尾结点
    head->next = NULL;

    // 返回新的头结点,即原链表的尾结点
    return newTail;
}


网站公告

今日签到

点亮在社区的每一天
去签到