链表——206. 反转链表(这题很重要)

简介: 本专栏按照数组—链表—哈希—字符串—栈与队列—二叉树—回溯—贪心—动态规划—单调栈的顺序刷题,采用代码随想录所给的刷题顺序,一个正确的刷题顺序对算法学习是非常重要的,希望对大家有帮助

1 题目描述

  1. 反转链表

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

链表反转是⼀个出现频率特别⾼的算法题,笔者过去这些年⾯试,⾄少遇到过七⼋次。其中更夸张的是曾经两天写
了三次,上午YY,下午⾦⼭云,第⼆天快⼿。链表反转在各⼤⾼频题排名⽹站也⻓期占领前三。⽐如⽜客⽹上这个
No 1 好像已经很久了。所以链表反转是我们学习链表最重要的问题,没有之⼀。
那为什么反转这么重要呢?因为反转链表涉及结点的增加、删除等多种操作,能⾮常有效考察对指针的驾驭能⼒和
思维能⼒。
另外很多题⽬也都要⽤它来做基础, 例如指定区间反转、链表K个⼀组翻转。还有⼀些在内部的某个过程⽤到了反
转,例如两个链表⽣成相加链表。还有⼀种是链表排序的,也是需要移动元素之间的指针,难度与此差不多。接下
来我们就具体看⼀下每个题⽬。

请将这个算法背下来!!!!它太重要了

2 题目示例

image.png

image.png

示例 3:

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

3 题目提示

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

4 思路

方法一:迭代
假设存在链表 1 \rightarrow 2 \rightarrow 3 \rightarrow \varnothing1→2→3→∅,我们想要把它改成 \varnothing \leftarrow 1 \leftarrow 2 \leftarrow 3∅←1←2←3。

在遍历列表时,将当前节点的 \textit{next}next 指针改为指向前一个元素。由于节点没有引用其上一个节点,因此必须事先存储其前一个元素。在更改引用之前,还需要另一个指针来存储下一个节点。不要忘记在最后返回新的头引用!

复杂度分析

时间复杂度:O(n)O(n),假设 nn 是列表的长度,时间复杂度是 O(n)O(n)。
空间复杂度:O(1)O(1)。

image.png

5 我的答案

方法一:

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;
        while (curr != null) {
            ListNode nextTemp = curr.next;
            curr.next = prev;
            prev = curr;
            curr = nextTemp;
        }
        return prev;
    }
}

方法二:

class Solution {

public ListNode reverseList(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }
    ListNode p = reverseList(head.next);
    head.next.next = head;
    head.next = null;
    return p;
}

}

最后再用双指针做一遍:

妖魔化的双指针

  • 原链表的头结点就是反转之后链表的尾结点,使用 headhead 标记 .
  • 定义指针 curcur,初始化为 headhead .
  • 每次都让 headhead 下一个结点的 nextnext 指向 curcur ,实现一次局部反转
  • 局部反转完成之后,curcur 和 headhead 的 nextnext 指针同时 往前移动一个位置
  • 循环上述过程,直至 curcur 到达链表的最后一个结点 .
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        while(cur != null)
        {
            ListNode t = cur.next;  //保留cur的后继节点
            cur.next = pre;         //cur指向其前驱节点
            pre = cur;
            cur = t;
        }
        return pre;                    //最后返回pre
    }
}
相关文章
|
4月前
|
索引
【力扣刷题】两数求和、移动零、相交链表、反转链表
【力扣刷题】两数求和、移动零、相交链表、反转链表
36 2
【力扣刷题】两数求和、移动零、相交链表、反转链表
|
10月前
|
算法
【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表
【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表
76 0
|
10月前
|
测试技术
【LeetCode题目详解】(二)206.反转链表、876.链表的中间结点
【LeetCode题目详解】(二)206.反转链表、876.链表的中间结点
66 0
|
11月前
【面试必刷TOP101】反转链表 & 链表内指定区间反转
【面试必刷TOP101】反转链表 & 链表内指定区间反转
53 0
|
11月前
【Leetcode -86.分隔链表 -92.反转链表Ⅱ】
【Leetcode -86.分隔链表 -92.反转链表Ⅱ】
36 0
|
11月前
代码随想录Day03 | 链表基础1 LeetCode T203 移除链表元素 T707设计链表 T206 反转链表
代码随想录Day03 | 链表基础1 LeetCode T203 移除链表元素 T707设计链表 T206 反转链表
43 0
|
4月前
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点.
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点
43 1
|
4月前
|
C++
[leetcode 链表] 反转链表 vs 链表相交
[leetcode 链表] 反转链表 vs 链表相交
|
4月前
|
C语言 C++ 索引
【力扣】141. 环形链表、160. 相交链表、206.反转链表、234. 回文链表
【力扣】141. 环形链表、160. 相交链表、206.反转链表、234. 回文链表
|
4月前
|
C语言
反转链表、链表的中间结点、合并两个有序链表【LeetCode刷题日志】
反转链表、链表的中间结点、合并两个有序链表【LeetCode刷题日志】