1.题目描述:
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
/**
* public class ListNode {
* int val;
* ListNode next = null;
*
* ListNode(int val) {
* this.val = val;
* }
* }
*
*/
2.解题思路:
方法一:借助堆栈的“后进先出”实现
方法二:借助递归实现(递归的本质还是使用了堆栈结构)
3. 代码实现
方法一:
import java.util.Stack;
import java.util.ArrayList;
public class Print_List_From_Tail_To_Head {
public static void main(String[] srgs){
//第一步:准备数据
ListNode root = new ListNode(1);
ListNode n1 = new ListNode(2) ;
ListNode n2 = new ListNode(3) ;
// 连接节点
root.setNext(n1);
n1.setNext(n2);
Print_List_From_Tail_To_Head mm=new Print_List_From_Tail_To_Head();
ArrayList<Integer> list=mm.printListFromTailToHead(root);
System.out.println("list:"+list);
}
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
Stack<Integer> stack = new Stack<>();
while (listNode != null) {
stack.push(listNode.val);
listNode = listNode.next;
}
ArrayList<Integer> list = new ArrayList<>();
while (!stack.isEmpty()) {
list.add(stack.pop());
}
return list;
}
}
//定义节点
class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
public void setNext(ListNode next){
this.next = next ;
}
}
运行:
list:[3, 2, 1]
方法二:
import java.util.ArrayList;
public class Print_List_From_Tail_To_Head {
ArrayList<Integer> arrayList = new ArrayList<Integer>();
public static void main(String[] srgs){
//第一步:准备数据
ListNode root = new ListNode(1);
ListNode n1 = new ListNode(2) ;
ListNode n2 = new ListNode(3) ;
// 连接节点
root.setNext(n1);
n1.setNext(n2);
Print_List_From_Tail_To_Head mm=new Print_List_From_Tail_To_Head();
ArrayList<Integer> list=mm.printListFromTailToHead(root);
System.out.println("list:"+list);
}
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
if(listNode!=null) {
this.printListFromTailToHead(listNode.next);
this.arrayList.add(listNode.val);
}
System.out.println(this.arrayList);
return this.arrayList;
}
}
//定义节点
class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
public void setNext(ListNode next){
this.next = next ;
}
}
运行:
[]
[3]
[3, 2]
[3, 2, 1]
list:[3, 2, 1]
4. 补充
(2)一个Java源文件中为什么最多只能有一个public类?
一个Java源文件中可以有多个类,但最多只能有一个用public修饰的类,但也可以没有一个public修饰的类。当这个源文件中有一个public修饰的类时,源文件的名称必须和public修饰的类的类名完全一致(区分大小写)。为什么这时的取名要完全一致:
- 因为jvm虚拟机为了提高查找类的速度,使用import语句导入的时候,只会导入对应空间的文件名所对应的class文件,而public文件是大家都要使用的,因此直接导入这个类名对应的class文件即可。
- 如果编译单元中包含了public类,那么该类对应的字节码文件是需要被类加载器加载的,这时候就需要让类加载器知道该字节码文件的位置,所以就要确保该类与Java文件名称一致。
- 同时,如果有两个public类在同一个文件中,而一个文件只能有一个名称,故两个public类的名称就不能同时和文件名一样,这就造成至少其中有一个public类在编译的时候编译不通过,产生类似的提示(对于一个public类,它是可以被项目中任何一个类所引用的,只需在使用它前import一下它所对应的class文件即可,将类名与文件名一一对应就可以方便虚拟机在相应的路径(包名)中找到相应的类的信息。如果不这么做的话,就很难去找,而且开销也会很大)。
当这个源文件中一个public修饰的类都没有时,源文件的名称可以不一致,但必须符合命名规则。这里为什么可以不一致呢?
- Java编译器在编译的时候,如果整个Java文件(编译单元)都没有public类(对外的公开接口类),类加载器子就无需从这方面直接去加载该编译单元产生的所有的字节码文件(.class文件),那么也就是无需去寻找编译后字节码文件存放位置。而类名和文件名一致是为了方便虚拟机在相应的路径中找到相应的类所对应的字节码文件。所以在没有public类的Java文件中,文件名和类名都没什么联系。