力扣206. 反转链表

题目来源(力扣):

https://leetcode.cn/problems/reverse-linked-list/description/

题目描述:

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

基本思路:

利用pre指向上一个节点,p指向当前节点,nex指向下一个节点。
具体而言,每次循环先保存nex=p->next,然后更改p->next为pre。这样就完成了一次链表的反转。
之后再修改pre=p; p=nex; 为下一次循环做准备

边界为p==nullptr,即完成了所有链表节点的反转,且此时pre来到了原链表的末尾(因此反转后的链表头结点正好是pre)

所以就是

  while(p!=nullptr){
    nex=p->next;
    p->next=pre;
    pre=p;
    p=nex;
  }

另外,该迭代写法可以改成递归写法,实际上的逻辑是一样的~

参考《代码随想录》如下:

代码实现-迭代(好理解):

class Solution
{
public:
    ListNode *reverseList(ListNode *head)
    {
        ListNode *pre = nullptr, *p = head, *nex;
        while (p)
        {
            nex = p->next;
            p->next = pre;
            pre = p;
            p = nex;
        }
        return pre;
    }
};

代码实现-递归:

class Solution
{
public:
    ListNode *reverse(ListNode *pre, ListNode *p)
    {
        if (p == nullptr)
            return pre;
        // 每层递归做2件事:记录nex、更改当前p的指向为pre
        ListNode *nex = p->next;//1.
        p->next = pre; //2.
        return reverse(p, nex); // 这句的逻辑和迭代法完全相同,等价于 pre=p,p=nex; 相当于为下一次操作做准备
    }
    ListNode *reverseList(ListNode *head)
    {
        ListNode *pre = nullptr, *p = head;
        return reverse(pre, p);
    }
};

补充

LinkNode定义为:

struct ListNode {
    int val;
    ListNode *next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode *next) : val(x), next(next) {}
};

算法时间复杂度为 O(n)

posted @ 2024-10-17 10:46  HB_Computer  阅读(39)  评论(0)    收藏  举报