题目描述

输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。

解题思路

思路一:使用头插法

使用头插法可以得到一个逆序的链表。遍历链表,每次将所遍历节点插入到链表的头部。

头结点和第一个节点的区别:

  • 头结点是在头插法中使用的一个额外节点,这个节点不存储值;
  • 第一个节点就是链表的第一个真正存储值的节点。
/**
* public class ListNode {
* int val;
* ListNode next = null;
*
* ListNode(int val) {
* this.val = val;
* }
* }
*
*/
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> res = new ArrayList<Integer>();
if(listNode == null) return res;
ListNode newList = new ListNode(-1);
while(listNode != null){
ListNode tmp = listNode.next;
listNode.next = newList.next;
newList.next = listNode;
listNode = tmp;
}
while(newList.next != null){
res.add(newList.next.val);
newList = newList.next;
}
return res;
}
}

运行结果:

运行时间:17ms

占用内存:9324k

类似做法:遍历链表,创建一个新的链表,每次将遍历的节点放在开头

import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> res = new ArrayList<Integer>();
if(listNode == null) return res;
ListNode newList = new ListNode(listNode.val);
ListNode nextNode = listNode.next;
while(nextNode != null){
ListNode insert = new ListNode(nextNode.val);
insert.next = newList;
newList = insert;
nextNode = nextNode.next;
}
res.add(newList.val);
nextNode = newList.next;
while(nextNode != null){
res.add(nextNode.val);
nextNode = nextNode.next;
}
return res;
}
}

结果:

运行时间:21ms

占用内存:9412k

思路二:递归

/**
* public class ListNode {
* int val;
* ListNode next = null;
*
* ListNode(int val) {
* this.val = val;
* }
* }
*
*/
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
// 递归
ArrayList<Integer> res = new ArrayList<Integer>();
if(listNode != null){
res.addAll(printListFromTailToHead(listNode.next));
res.add(listNode.val);
}
return res;
}
}

结果:

运行时间:19ms

占用内存:9436k

思路三:栈

/**
* public class ListNode {
* int val;
* ListNode next = null;
*
* ListNode(int val) {
* this.val = val;
* }
* }
*
*/
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
// 栈
Stack<Integer> stk = new Stack<Integer>();
while(listNode != null){
stk.add(listNode.val);
listNode = listNode.next;
}
ArrayList<Integer> res = new ArrayList<Integer>();
while(!stk.isEmpty()){
res.add(stk.pop());
}
return res;
}
}

结果:

运行时间:22ms

占用内存:9424k

思路参考:https://www.nowcoder.com/discuss/198840

剑指Offer编程题(Java实现)——从尾到头打印链表的更多相关文章

  1. C++版 - 剑指offer 面试题5:从尾到头打印链表 题解

    面试题5:从尾到头打印链表 提交网址: http://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035?tpId=13&tq ...

  2. 【剑指offer】面试题 6. 从尾到头打印链表

    面试题 6. 从尾到头打印链表 NowCoder 题目描述 输入一个链表的头结点,从尾到头反过来打印出每个结点的值. Java 实现 ListNode Class class ListNode { i ...

  3. 剑指offer编程题Java实现——面试题12打印1到最大的n位数

    题目:打印1到最大的n位数 输入数字n,按顺序打印输出从1到最大的n位十进制数,比如输入3,打印从1到999. 这道题考察的地方是如何表示大数问题.由于n是任意大的数组,如果n太大的话n位数就超过了l ...

  4. 剑指offer 面试题5 : 从尾到头打印链表

    题目: 输入一个链表的头结点,从尾到头反过来打印出每个节点的值.链表结点定义如下: struct ListNode { int m_nKey; ListNode* m_pNext; }; 思路: 通常 ...

  5. 剑指offer 面试题6:从尾到头打印链表

    题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 编程思想 从前往后遍历,将值存入栈中,然后打印栈中内容即可. 编程实现 /** * struct ListNode { * ...

  6. 剑指Offer:面试题5——从尾到头打印链表(java实现)

    问题描述:输入一个链表的头结点,从尾巴到头反过来打印出每个结点的值. 首先定义链表结点 public class ListNode { int val; ListNode next = null; L ...

  7. 《剑指offer》面试题5 从尾到头打印链表 Java版

    书中方法一:反转应该立刻想到栈,利用一个栈完成链表的反转打印,但是用了额外的O(n)空间. public void printFromTail(ListNode first){ Stack<Li ...

  8. 剑指Offer(三):从尾到头打印链表

    一.前言 刷题平台:牛客网 二.题目 输入一个链表,返回一个反序的链表. 1.思路 通常,这种情况下,我们不希望修改原链表的结构.返回一个反序的链表,这就是经典的"后进先出",我们 ...

  9. 剑指Offer面试题:4.从尾到头打印链表

    一.题目:从尾到头打印链表 题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值. 到解决这个问题肯定要遍历链表.遍历的顺序是从头到尾的顺序,可输出的顺序却是从尾到头.也就是说第一个遍历到的结 ...

  10. 剑指offer——面试题6:从尾到头打印链表

    #include"iostream" #include"stdio.h" #include"stack" using namespace s ...

随机推荐

  1. shell之文本过滤(awk)

    shell之文本过滤(awk) 分类: linux shell脚本学习2012-09-19 15:53 1241人阅读 评论(0) 收藏 举报 shell正则表达式脚本任务语言 如果要格式化报文或从一 ...

  2. Leaflet使用vector tiles样式设置

    //point style var myIcon = L.icon({ iconUrl: 'css/images/dian.svg', // shadowUrl: 'css/images/leaf-s ...

  3. Nginx模块开发实验

    工作原理: 当nginx接到 一个http请求之后,会找通过查找配置文件,并在配置文件中找到相应的地址映射,该地址也叫location block,而location中配置的文件会启动 相应的bloc ...

  4. EventArgs

    序言 DataEventArgs<DataSet> arg = new DataEventArgs<DataSet>(ds); 事件总线 什么是事件总线 我们知道事件是由一个P ...

  5. ZOJ 1610 Count the Colors (线段树成段更新)

    题意 : 给出 n 个染色操作,问你到最后区间上能看见的各个颜色所拥有的区间块有多少个 分析 : 使用线段树成段更新然后再暴力查询总区间的颜色信息即可,这里需要注意的是给区间染色,而不是给点染色,所以 ...

  6. java jts

    来自:UCMapForOpenGIS https://bbs.csdn.net/topics/380204896?list=992863 对比 其实geotools就是基于jts开发的,而geoser ...

  7. Logger工具类

    org.slf4j.Logger的简单封装,传入所在类的class,和类名或全类名. public class LoggerFactory { public static Logger getLogg ...

  8. D. Print a 1337-string...

    D. Print a 1337-string... 输出一个字符串 里面包含n个子序列 1337 #include<bits/stdc++.h> using namespace std; ...

  9. [CSP-S模拟测试]:优化(贪心+DP)

    题目描述 $visit\text{_}world$发现有下优化问题可以用很平凡的技巧解决,所以他给你分享了这样一道题:现在有长度为$N$的整数序列$\{ a_i\}$,你需要从中选出$K$个不想叫的连 ...

  10. GIT的工作原理和基本命令

    1.GIT的工作原理 工作区:我们写代码的地方. 暂存区:临时存储用的. 历史区:生成历史版本的地方. 提交流程:工作区->暂存区->历史区 图示: 2.GIT的全局配置 3.创建仓库完成 ...