题目描述

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

题目代码

/**
* @program: JavaCode
* @description:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
* @author: Yukai Fan
* @create: 2018-08-15 20:28
**/
public class LinkListPrint { public static void main(String[] args) {
LinkListPrint llp = new LinkListPrint(); ListNode listNode = new ListNode(1);
listNode.next = new ListNode(2);
listNode.next.next = new ListNode(3);
listNode.next.next.next = new ListNode(4); ArrayList<Integer> arrayList = printLinkListFromTailToHead(listNode);
ArrayList<Integer> arrayList2 = printLinkListFromTailToHead2(listNode);
ArrayList<Integer> arrayList3 = llp.printLinkListFromTailToHead3(listNode); System.out.println(arrayList);
System.out.println(arrayList2);
System.out.println(arrayList3);
}
/*
方法一:利用堆栈后进先出的特性,将链表的值先push堆栈,然后在一一将值pop到ArrayList集合中输出
*/
public static ArrayList<Integer> printLinkListFromTailToHead(ListNode listNode) {
Stack<Integer> stack = new Stack<>();
while (listNode != null) {
stack.push(listNode.val);
listNode = listNode.next;
}
ArrayList<Integer> arrayList = new ArrayList<>();
while (!stack.isEmpty()) {
arrayList.add(stack.pop());
}
return arrayList;
}
/*
方法二:利用Collections集合的API方法reverse()可以反转集合中的数值
*/
public static ArrayList<Integer> printLinkListFromTailToHead2(ListNode listNode) {
ArrayList<Integer> list = new ArrayList<>();
while (listNode != null) {
list.add(listNode.val);
listNode = listNode.next;
}
if (list != null && list.size() > 0) {
Collections.reverse(list);
}
return list;
} /*
方式三:利用递归的方式(超简洁)
作者:grass_stars
递归的点在printListFromTailToHaed(listNode.next)这个节点,
那么在最后一次递归方法返回以后,每一层的递归方法都会做一个arrayList.add(lizxstNode.val)这个操作,
从最后一次到第一次,逆向的调用了后面的方法。因为之前的递归点已经返回了。
*/
ArrayList<Integer> list = new ArrayList<>();
public ArrayList<Integer> printLinkListFromTailToHead3(ListNode listNode) {
if (listNode != null) {
this.printLinkListFromTailToHead3(listNode.next);
list.add(listNode.val);
}
return list;
}
}

题目延伸

1、java堆、栈、堆栈的区别

2、java的main方法为什么必须是static的,它调用的方法是不是一定要static的

为什么main方法是静态的(static)

  1. 正因为main方法是静态的,JVM调用这个方法就不需要创建任何包含这个main方法的实例。
  2. 因为C和C++同样有类似的main方法作为程序执行的入口。
  3. 如果main方法不声明为静态的,JVM就必须创建main类的实例,因为构造器可以被重载,JVM就没法确定调用哪个main方法。
  4. 静态方法和静态数据加载到内存就可以直接调用而不需要像实例方法一样创建实例后才能调用,如果main方法是静态的,那么它就会被加载到JVM上下文中成为可执行的方法。
为什么main方法是公有的(public)

Java指定了一些可访问的修饰符如:private、protected、public,任何方法或变量都可以声明为public,Java可以从该类之外的地方访问。因为main方法是公共的,JVM就可以轻松的访问执行它。

为什么main方法没有返回值(Void) 

因为main返回任何值对程序都没任何意义,所以设计成void,意味着main不会有任何值返回

为什么main方法是静态的(static),它调用的方法是不是一定要static的

  1. static表示这个方法不属于这个内,而是所有内对象共有的。会在类对象定义之前,这样的方法就已经构建完成,就是这个方法游离于类对象之外,否则想要使用main函数,就要先定义类,而main又是所有程序的入口,这样就会矛盾了。

  2. 而非static的方法,成员都要通过类对象调用;而静态的可以直接通过类名调用,而同一个类中,类名也可以省掉。

  3. 没有static修饰的方法,在调用的时候需要先创造对象。有static修饰的方法,在调用的时候直接调用也就是说:没有static修饰的,它们在生成的时候,就属于对象。有static修饰的,它们在生成的时候,就属于类。main方法是java自带的,我们创建它的时候,就已经注定了它的必然性——静态方法。在静态方法中,只能访问静态的变量,还有静态的其他方法。

总结

  1. main方法必须声明为public、static、void,否则JVM没法运行程序
  2. 如果JVM找不到main方法就抛出NoSuchMethodError:main异常,例如:如果你运行命令:java HelloWrold,JVM就会在HelloWorld.class文件中搜索public static void main (String[] args) 放法
  3. main方式是程序的入口,程序执行的开始处。
  4. main方法被一个特定的线程”main”运行,程序会一直运行直到main线程结束或者non-daemon线程终止。
  5. 当你看到“Exception in Thread main”如:Excpetion in Thread main:Java.lang.NullPointedException ,意味着异常来自于main线程
  6. 你可以声明main方法使用java1.5的可变参数的方式如:
    public  static void main(String... args)
  7. 除了static、void、和public,你可以使用final,synchronized、和strictfp修饰符在main方法的签名中,如:
    public  strictfp final  synchronized static  void main(String[] args)
  8. main方法在Java可以像其他方法一样被重载,但是JVM只会调用上面这种签名规范的main方法。
  9. 你可以使用throws子句在方法签名中,可以抛出任何checked和unchecked异常
  10. 静态初始化块在JVM调用main方法前被执行,它们在类被JVM加载到内存的时候就被执行了。

转载请注明出处:http://www.cnblogs.com/numen-fan/

3、递归

/**
* @program: JavaCode
* @description:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
* @author: Yukai Fan
* @create: 2018-08-15 20:28
**/
public class LinkListPrint { public static void main(String[] args) {
LinkListPrint llp = new LinkListPrint(); ListNode listNode = new ListNode();
listNode.next = new ListNode();
listNode.next.next = new ListNode();
listNode.next.next.next = new ListNode(); ArrayList<Integer> arrayList = printLinkListFromTailToHead(listNode);
ArrayList<Integer> arrayList2 = printLinkListFromTailToHead2(listNode);
ArrayList<Integer> arrayList3 = llp.printLinkListFromTailToHead3(listNode); System.out.println(arrayList);
System.out.println(arrayList2);
System.out.println(arrayList3);
}
/*
方法一:利用堆栈后进先出的特性,将链表的值先push堆栈,然后在一一将值pop到ArrayList集合中输出
*/
public static ArrayList<Integer> printLinkListFromTailToHead(ListNode listNode) {
Stack<Integer> stack = new Stack<>();
while (listNode != null) {
stack.push(listNode.val);
listNode = listNode.next;
}
ArrayList<Integer> arrayList = new ArrayList<>();
while (!stack.isEmpty()) {
arrayList.add(stack.pop());
}
return arrayList;
}
/*
方法二:利用Collections集合的API方法reverse()可以反转集合中的数值
*/
public static ArrayList<Integer> printLinkListFromTailToHead2(ListNode listNode) {
ArrayList<Integer> list = new ArrayList<>();
while (listNode != null) {
list.add(listNode.val);
listNode = listNode.next;
}
if (list != null && list.size() > ) {
Collections.reverse(list);
}
return list;
} /*
方式三:利用递归的方式(超简洁)
作者:grass_stars
递归的点在printListFromTailToHaed(listNode.next)这个节点,
那么在最后一次递归方法返回以后,每一层的递归方法都会做一个arrayList.add(lizxstNode.val)这个操作,
从最后一次到第一次,逆向的调用了后面的方法。因为之前的递归点已经返回了。
*/
ArrayList<Integer> list = new ArrayList<>();
public ArrayList<Integer> printLinkListFromTailToHead3(ListNode listNode) {
if (listNode != null) {
this.printLinkListFromTailToHead3(listNode.next);
list.add(listNode.val);
}
return list;
}
}

java基础编程——链表反转的更多相关文章

  1. 6、50道JAVA基础编程练习题跟答案

    50道JAVA基础编程练习题 [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 程序分析 ...

  2. MQ java 基础编程

    MQ java 基础编程 编写人:邬文俊 编写时间 : 2006-2-16 联系邮件 : wenjunwu430@gmail.com 前言 通过 2 个多星期对 MQ 学习,在 partner 丁 & ...

  3. 50道JAVA基础编程练习题

    50道JAVA基础编程练习题 [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子对数为多少? 程序分析 ...

  4. 50道JAVA基础编程练习题 - 题目

    50道JAVA基础编程练习题[1]题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? [2]题目:判断 ...

  5. 【Java数据结构】Java数据结构之链表反转

    我们都知道用C可以很简单的实现单链表反转,今天来学习下,在Java中如何实现链表反转. 思路很简单,定义一个类,这个类分成2块,一块是表示自身的标志,另外一个存储指向下一个元素的引用.通过互换相邻两个 ...

  6. JAVA基础——编程练习(二)

    JAVA编程练习(二) 今天我为了巩固之前的java基础知识的学习,再次进行实战演习,编写了一个小小的java控制台程序,主要是运用java面向对象的思想来完成这个小项目. 一.项目背景介绍 根据所学 ...

  7. Java实现单链表反转操作

    单链表是一种常见的数据结构,由一个个节点通过指针方式连接而成,每个节点由两部分组成:一是数据域,用于存储节点数据.二是指针域,用于存储下一个节点的地址.在Java中定义如下: public class ...

  8. java实现单链表反转

    一.简介 经查阅,主要有两种方法实现链表反转,递归反转法和遍历反转法: 递归: 在反转当前结点之前先反转其后边的结点,即.从尾结点开始逆向反转各个节点的指针域指向: 遍历:从前往后反转各个结点的指针域 ...

  9. java实现单链表反转(倒置)

    据说单链表反转问题面试中经常问,而链表这个东西相对于数组的确稍微难想象,因此今天纪录一下单链表反转的代码. 1,先定义一个节点类. 1 public class Node { 2 int index; ...

随机推荐

  1. 误删重要文件怎么办?学会Linux 救援模式再也不担心

    背景 在运用Linux时会出现一些误操作,导致系统无法正常使用,比如删除了某个重要依赖库,或者删除了rpm等等.在这里记录下具体的操作步骤,供以后参考. 意义 学会在使用Linux系统出现误删除系统重 ...

  2. promise封装小程序的请求类(request,清爽易懂)

    话不多说直接上代码,清爽易懂: import { config } from '../config.js' const tips = { 1:'抱歉出现了一个错误', 2:'网络错误', 1005:' ...

  3. Exadata Adaptive Scrubbing Schedule

    1.为什么要引入"Hard Disk Scrub and Repair"特性 在exadata的11.2.3.3.0版本中,开始引进了"Automatic Hard Di ...

  4. java 正则简单使用

    查找是否包含字串 查询是否包含 #{name} 片段 这里有包含所以返回true String context = "select * from t_user where (name = # ...

  5. 消息中间件的研究 (四)RabbitMQ、Kafka、RocketMQ消息中间件的对比及分析

    RabbitMQ:     RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现.AMQP的主要特征是面向消息.队列.路由(包括点对点和发布/订阅).可靠性.安全.AM ...

  6. Luogu P3546 [POI2012]PRE-Prefixuffix 神奇的递推+哈希

    设$f[i]$表示切掉前$i$位和后$i$位后,即剩下$s[i+1]到s[n-i]$,的公共前后缀长度.此时我们发现,$f[i-1]$相对于$f[i]$少切了两个$char$,所以有$f[i-1]\l ...

  7. 使用命令行+代理更新Android SDK

    在无桌面的Linux上面安装Jenkins,要配置成Andorid 的持续集成环境Jenkins持续集成Android项目,需要在无桌面的Linux(ubuntu,centos)上安装Android ...

  8. JS绑定事件和移除事件的处理方法

    addEventListener()与removeEventListener()用于处理指定和删除事件处理程序操作.所有的DOM节点中都包含这两种方法,并且它们都接受3个参数:要处理的事件名.作为事件 ...

  9. C++中的引用和指针

    引用和指针有何区别?何时只能使用指针而不能使用引用?    引用是一个别名,不能为 NULL 值,不能被重新分配:指针是一个存放地址的变量.当需要对变量重新赋以另外的地址或赋值为 NULL 时只能使用 ...

  10. 一个关于laravel部署的讲座

    https://pusher.com/sessions/meetup/laravel-nigeria/deploying-your-laravel-application