【刷题之路】LeetCode 206. 反转链表

一、题目描述

原题连接: 206. 反转链表
题目描述:
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

在这里插入图片描述
输入: head = [1,2,3,4,5]
输出: [5,4,3,2,1]

示例 2:

在这里插入图片描述
输入: head = [1,2]
输出: [2,1]

示例 3:

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

提示:
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000

二、解题

1、方法1——改变指针方向

1.1、思路分析

因为链表的节点在内存中的地址是随机的,它们之间的联系方式只是通过一个next指针来联系:
在这里插入图片描述
所以我们其实只需要将各个节点之间的指针的方向反转过来,然后再将第一节点的next置为NULL将最后一个节点当做新的头节点即可:
在这里插入图片描述
而因为单链表的局限性,我们想要完成翻转就必须使用三个指针,pre、cur、next辅助反转,如下图所示:
在这里插入图片描述
只有这样我们才能做到在翻转cur的next方向时候,既能找到cur的前一个节点,也能保证在反转之后找到cur的下一个节点:
在这里插入图片描述
翻转完一个节点后,我们就让pre = cur,cur = next,next = next->next,就这样一直迭代地往后走就行了:
在这里插入图片描述
对后当cur为NULL时,就说明了我们已经把链表中所有的节点的指针方向全都反转过来了,所以结束条件就是cur为NULL:
在这里插入图片描述
所以我们之后返回pre作为新的头节点即可。

1.2、代码实现

有了以上思路,那我们写起代码来也就水到渠成了:

struct ListNode* reverseList(struct ListNode* head){
    if (NULL == head) {
        return NULL;
    }    
    struct ListNode *Pre = NULL;
    struct ListNode *Cur = head;
    struct ListNode *Next = head->next;
    
    while (Cur) {
        // 翻转
        Cur->next = Pre;

        // 迭代
        Pre = Cur;
        Cur = Next;
        if (Next) {
            Next = Next->next;
        }
    }
    return Pre;
}

时间复杂度:O(n),n为链表的长度。
空间复杂度:O(1),我们只需要用到常数级的额外空间。

2、方法2——头插到新链表

2.1、思路分析

还有一个更简洁的方式就是将原链表中的节点按顺序头插到一个新的链表中,这样当我们头插完所有的节点得到的新链表也就是翻转完成后的链表:
在这里插入图片描述
同样的,我们还是需要两个指针cur和next来帮我们完成头插,在每次将cur头插到新链表之前,先让next保存cur的下一个节点:
在这里插入图片描述
最后我们返回新的头指针newhead即可。

2.2、代码实现

有了以上思路,那我们写起代码来也就水到渠成了

 struct ListNode* reverseList(struct ListNode* head) {
     struct ListNode* Cur = head;
     struct ListNode* newhead = NULL; // 新的头指针
     struct ListNode* Next = NULL; // 保存cur的下一个节点,以辅助头插
     while (Cur) {
         Next = Cur->next;
         // 头插
         Cur->next = newhead;
         newhead = Cur;

         // 迭代往后走
         Cur = Next;
     }
     return newhead;
 }

时间复杂度:O(n),n为链表的长度。
空间复杂度:O(1),我们只需要用到常数级的额外空间。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

林先生-1

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

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

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

打赏作者

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

抵扣说明:

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

余额充值