3.从尾到头打印链表
(输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。)
(这个其实就是类似起遍历作用的,到最后一个的时候方法栈开始返回,因为题目要求从尾到头.)
注意:
1.ArrayList是实现了基于动态数组的数据结构,非线程安全的,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
方法一:递归
import java.util.ArrayList;
public class Solution {
ArrayList arraylist=new ArrayList();
public ArrayList printListFromTailToHead(ListNode listNode) {
if(listNode!=null){//判断当前节点是否为空,直到到达最后一个节点
printListFromTailToHead(listNode.next);//指向下一个节点
arraylist.add(listNode.val);//把当前遍历的节点数据放入arraylist集合
}
//Add方法用于添加一个元素到当前列表的末尾 —尾插
return arraylist;//到这一步说明找到了最后一个节点
}
}
单链表常见操作的实现,包括链表结点添加、删除;链表正向遍历和反向遍历、链表排序、判断链表是否有环、是否相交、获取某一结点等。
以下是定义一个类作为节点
class Link{ //一个链表类
public Entry head;//定义链表的头结点
public Link(){//初始化链表时创建一个头结点
head = new Entry();
}
}
class Entry{ //Entry 节点类
int data;//数据域
Entry next;//地址域
public Entry(){//将头结点初始化为 data=-1 next=null
data = -1;
next = null;
}
public Entry(int val){//其他结点所需的构造函数
data = val;
next = null;
}
}
List接口中的add方法有如下两种重载方式:
① boolean add(E e);
② void add(int index, E element);
其中,方法①用于向列表的末尾插入新元素,这也是List接口中最常用的插入方法;方法②则可以在插入操作过程中指定插入的位置,此时,会自动将当前位置及只有的元素后移进行插入,需要注意的是,参数index的值不可大于当前list的容量,即在使用此方法填充一个list时,必须以0开始依次填充。可以参考如下的示例代码:
二刷:使用了栈的特点,先进后出的思想,一刷用的是递归的思路
(有三种思路,第一就是利用栈先入后出的特性完成,第二就是存下来然后进行数组翻转。第三是利用递归。)
题目需求是从尾到头,即先进后出,使用栈
import java.util.Stack;
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
Stack<Integer> st=new Stack<>();//栈后进先出。。。
while(listNode!=null){
st.push(listNode.val); //最后一个节点最后一个压栈
listNode=listNode.next;
}
ArrayList<Integer> list=new ArrayList<>();
while(!st.isEmpty()){
list.add(st.pop());//弹栈,最后一个节点先弹栈,放入集合中。后续尾插在集合中
}
return list;
}
}