链表反转的两种实现方法,后一种击败了100%的用户!

简介: 链表反转的两种实现方法,后一种击败了100%的用户!

链表反转是一道很基础但又非常热门的算法面试题,它也在《剑指Offer》的第 24 道题出现过,至于它有多热(门)看下面的榜单就知道了。

image.png

image.png


从牛客网的数据来看,链表反转的面试题分别霸占了【上周考过】和【研发最爱考】的双重榜单,像网易、字节等知名互联网公司都考过,但通过率却低的只有 30%,所以本文我们就来学习一下反转链表的两种实现方法。

排行榜数据:https://www.nowcoder.com/activity/oj


题目

标题:剑指 Offer 24. 反转链表

描述:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:


输入: 1->2->3->4->5->NULL

输出: 5->4->3->2->1->NULL

LeetCode 链接:https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/

实现方式一:Stack

image.png

全部入栈:

image.png

因为栈是先进后出的数据结构,因此它的执行过程如下图所示:

image.png

image.png

image.png

最终的执行结果如下图所示:

image.png

实现代码如下所示:

public ListNode reverseList(ListNode head) {
    if (head == null) return null;
    Stack<ListNode> stack = new Stack<>();
    stack.push(head); // 存入第一个节点
    while (head.next != null) {
        stack.push(head.next); // 存入其他节点
        head = head.next; // 指针移动的下一位
    }
    // 反转链表
    ListNode listNode = stack.pop(); // 反转第一个元素
    ListNode lastNode = listNode; // 临时节点,在下面的 while 中记录上一个节点
    while (!stack.isEmpty()) {
        ListNode item = stack.pop(); // 当前节点
        lastNode.next = item;
        lastNode = item;
    }
    lastNode.next = null; // 最后一个节点赋为null(不然会造成死循环)
    return listNode;
}

LeetCode 验证结果如下图所示:

image.png

实现方式二:递归

image.png

image.pngimage.png

image.png

image.png

实现代码如下所示:

public static ListNode reverseList(ListNode head) {
    if (head == null || head.next == null) return head;
    // 从下一个节点开始递归
    ListNode reverse = reverseList(head.next);
    head.next.next = head; // 设置下一个节点的 next 为当前节点
    head.next = null; // 把当前节点的 next 赋值为 null,避免循环引用
    return reverse;
}


LeetCode 验证结果如下图所示:

image.png

总结

本文我们分别使用了 Stack 和递归的方法实现了链表反转的功能,其中 Stack 的实现方式是利用了栈后进先出的特性可以直接对链表进行反转,实现思路和实现代码都比较简单,但在性能和内存消耗方面都不是很理想,可以作为笔试的保底实现方案;而递归的方式在性能和内存消耗方面都有良好的表现,同时它的实现代码也很简洁,读者只需理解代码实现的思路即可。

相关文章
|
1月前
|
存储 算法 索引
模拟算法题练习(二)(DNA序列修正、无尽的石头)
模拟算法题练习(二)(DNA序列修正、无尽的石头)
|
3月前
leetcode-1688:比赛中的配对次数
leetcode-1688:比赛中的配对次数
20 0
|
6月前
|
算法
【算法挨揍日记】day01——双指针算法_移动零、 复写零
题目: 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。
32 0
|
存储 算法 前端开发
日拱算法:多数元素
给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
|
算法
(dfs)A -暴力模个拟(我是第一吗?我好像是第一个捏~)(原题目为Serval 的元素周期表)
(dfs)A -暴力模个拟(我是第一吗?我好像是第一个捏~)(原题目为Serval 的元素周期表)
41 0
|
Python
LeetCode 1688. 比赛中的配对次数
给你一个整数 n ,表示比赛中的队伍数。比赛遵循一种独特的赛制
81 0
|
算法
【刷算法】判断链表是否有环以及返回入环节点
【刷算法】判断链表是否有环以及返回入环节点
【刷算法】判断链表是否有环以及返回入环节点
再学一道算法题:CPA连续素数(我真的是签到题 )
天梯赛的一道签到题,自己最开始写出现运行超时,现已改正 本题给定一个数要求输出小于等于这个数并且相差为2的连续3个素数,比如3 5 7,若有多组要求每行输出三个,若没有则输出&quot;小伙汁 不讲武德 耗子尾汁&quot;。(素数,即为因子只有1 和 自己的数 4的因子有1 2 4 除了1和它自己还有其他因子所以它不是素数)。
再学一道算法题:CPA连续素数(我真的是签到题 )
|
算法
查找算法——抽签算法(假如我告诉你:不管多少元素,都只需要比对一次,你信还是不信?)
查找算法——抽签算法(假如我告诉你:不管多少元素,都只需要比对一次,你信还是不信?)
248 0
查找算法——抽签算法(假如我告诉你:不管多少元素,都只需要比对一次,你信还是不信?)
|
机器学习/深度学习
1823. 找出游戏的获胜者 :「模拟」&「约瑟夫环」
1823. 找出游戏的获胜者 :「模拟」&「约瑟夫环」