6. 从尾到头打印链表(剑指 Offer 题解Java版)

本文介绍三种从尾到头打印链表的方法:递归、头插法和栈。通过实例代码展示每种方法的具体实现,帮助读者理解并掌握链表逆序打印的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

6. 从尾到头打印链表

题目链接

牛客网

题目描述

从尾到头反过来打印出每个结点的值。
在这里插入图片描述

解题思路

1. 使用递归

要逆序打印链表 1->2->3(3,2,1),可以先逆序打印链表 2->3(3,2),最后再打印第一个节点 1。而链表 2->3 可以看成一个新的链表,要逆序打印该链表可以继续使用求解函数,也就是在求解函数中调用自己,这就是递归函数。

package 从尾到头打印链表;
/*
作者     :XiangLin
创建时间 :20/02/2020 22:06
文件     :printlist.java
IDE      :IntelliJ IDEA
*/

import java.util.ArrayList;

public class printlist {
    static class ListNode {
        int val;
        ListNode next = null;

        ListNode(int val) {
            this.val = val;
        }
    }
    public ArrayList<Integer> printListFormTailToHead(ListNode listNode){
        ArrayList<Integer> ret = new ArrayList<>();
        if (listNode != null){
            ret.addAll(printListFormTailToHead(listNode.next));
            ret.add(listNode.val);
        }
        return ret;
    }

    public static void main(String[] args) {
        ListNode listNode1 = new ListNode(1);
        ListNode listNode2 = new ListNode(2);
        ListNode listNode3 = new ListNode(3);
        listNode1.next = listNode2;
        listNode2.next = listNode3;

        printlist pl = new printlist();

        ArrayList<Integer> arrayList = new ArrayList();
        arrayList =pl.printListFormTailToHead(listNode1);
        System.out.println(arrayList);
    }
}

输出:
[3, 2, 1]

2. 使用头插法

头插法顾名思义是将节点插入到头部:在遍历原始链表时,将当前节点插入新链表的头部,使其成为第一个节点。

链表的操作需要维护后继关系,例如在某个节点 node1 之后插入一个节点 node2,我们可以通过修改后继关系来实现:

node3 = node1.next;
node2.next = node3;
node1.next = node2;

在这里插入图片描述
为了能将一个节点插入头部,我们引入了一个叫头结点的辅助节点,该节点不存储值,只是为了方便进行插入操作。不要将头结点与第一个节点混起来,第一个节点是链表中第一个真正存储值的节点。
在这里插入图片描述

package 从尾到头打印链表;/*
作者     :XiangLin
创建时间 :20/02/2020 22:30
文件     :printlist1.java
IDE      :IntelliJ IDEA
*/

import java.util.ArrayList;

public class printlist1 {
    static class ListNode{
        int val;
        ListNode next = null;
        ListNode(int val){
            this.val = val;
        }
    }
    public ArrayList<Integer> printListFormTailToHead(ListNode listNode){
        //头插法构建逆序链表
        ListNode head = new ListNode(-1);
        while (listNode != null){
            ListNode memo = listNode.next;
            listNode.next = head.next;
            head.next = listNode;
            listNode = memo;

        }
        //构建ArrayList
        ArrayList<Integer> ret = new ArrayList<>();
        head = head.next;
        while (head != null){
            ret.add(head.val);
            head = head.next;
        }
        return ret;
    }
    public static void main(String[] args) {
        ListNode listNode1 = new ListNode(1);
        ListNode listNode2 = new ListNode(2);
        ListNode listNode3 = new ListNode(3);
        listNode1.next = listNode2;
        listNode2.next = listNode3;
        printlist1 pl = new printlist1();
        ArrayList<Integer> arrayList = new ArrayList();
        arrayList =pl.printListFormTailToHead(listNode1);
        System.out.println(arrayList);
    }
}

输出:
[3, 2, 1]

3. 使用栈

栈具有后进先出的特点,在遍历链表时将值按顺序放入栈中,最后出栈的顺序即为逆序。
在这里插入图片描述

package 从尾到头打印链表;/*
作者     :XiangLin
创建时间 :20/02/2020 23:34
文件     :printlist3.java
IDE      :IntelliJ IDEA
*/

import java.util.ArrayList;
import java.util.Stack;

public class printlist3 {
    static class ListNode{
        int val;
        ListNode next = null;
        ListNode(int val){
            this.val = val;
        }
    }
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode){
        Stack<Integer> stack = new Stack<>();
        while (listNode != null){
            stack.add(listNode.val);
            listNode = listNode.next;
        }
        ArrayList<Integer> ret = new ArrayList<>();
        while (!stack.isEmpty())
            ret.add(stack.pop());
        return ret;
    }
    public static void main(String[] args) {
        ListNode listNode1 = new ListNode(1);
        ListNode listNode2 = new ListNode(2);
        ListNode listNode3 = new ListNode(3);
        listNode1.next = listNode2;
        listNode2.next = listNode3;
        printlist3 pl = new printlist3();
        ArrayList<Integer> arrayList = new ArrayList();
        arrayList = pl.printListFromTailToHead(listNode1);
        System.out.println(arrayList);
    }
}
输出:
[3, 2, 1]

个人微信公众号,专注于学习资源、笔记分享。我们一起成长,一起学习。一直纯真着,善良着,温情地热爱生活。
五角钱的程序员,专注于学习资源、笔记分享。
Your mind is like this water. When it is agitated, it becomes difficult to see, but if you allow it to settle, the answer becomes clear.
心如此水,乱则不明,但若心如止水,答案便尽现眼前。

向林
2020年2月20日于重庆城口
好好学习,天天向上,终有所获

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值