题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。
思路1:①第一个遍历的结点最后输出,最后一个遍历的结点最先输出。这是“后进后出”,可以用栈实现;②每经过一个结点的时候,把该结点放到一个栈中;③遍历完整个链表后,从栈顶开始逐个输出结点的值,此时输出的结点的顺序已经反过来了。
定义数据结构:
(1)Stack stack 用于保存链表中的元素
(2)ArrayList<Integer> list ,通过stack构造该list
步骤:
step1.遍历链表,同时将各节点值保存至stack
step2.弹出stack中所有元素,同时构造list数组
package offer;
import java.util.ArrayList;
import java.util.Stack;
class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
public class Solution6 {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
// if (listNode == null)
// return null;
if (listNode == null) {
ArrayList list = new ArrayList();
return list;
}
Stack<Integer> stack = new Stack<Integer>();
while (listNode != null) {
stack.push(listNode.val);
listNode = listNode.next;
}
ArrayList<Integer> array = new ArrayList<Integer>();
while (!stack.isEmpty()) {
array.add(stack.pop());
}
return array;
}
}
思路2:①用递归来实现,递归本质上也是栈;②每访问到一个结点的时候,先递归输出它后面的结点,再输出该结点自身。
定义数据结构:ArrayList<Integer> list
步骤:遍历链表时,调用自身同时将节点值保存到list中
package offer;
import java.util.ArrayList;
class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
public class Test6 {
ArrayList<Integer> arrayList = new ArrayList<Integer>();
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
if (listNode != null) {
this.printListFromTailToHead(listNode.next);
arrayList.add(listNode.val);
}
return arrayList;
}
}
知识点:循环、递归、栈3个相互关联的概念的理解
效率:循环>递归>栈
补充知识:
ArrayList
ArrayList类是一个特殊的数组。它来自于System.Collections命名空间;通过添加和删除元素,就可以动态改变数组的长度。
一、优点
①支持自动改变的大小的功能;②可以灵活的插入元素;③可以灵活的删除元素
二、缺点
跟一般的数组比起来,速度上差些。因为它是动态数组,初始化大小容量为4,当数据存满时扩容是以当前数组容量大小的2倍扩容,之后再把数组元素一个一个的存入,数组在扩容时浪费一定的内存空间和存储时间,而且,元素添加是一个装箱的过程。所以速度上稍微差些。
三、ArrayList的初始化
①不初始化起始容量:ArrayList al = new ArrayList(); //默认容量为0,当数组容量满时数组会自动以当前数组容量的2倍扩容
②初始化容量:ArrayList al =new ArrayList(3); //初始容量为3
③以一个集合或数组初始化:ArrayList al = new ArrayList(a); //a为集合或数组
④ArrayList<Integer>(); Integer是存储类型(整型)
四、ArrayList添加元素和删除元素
①添加元素使用自带方法add(object value);
ArrayList al = new ArrayList();
al.add("a");
②删除元素使用Remove(object value);
al.Remove(object obj);//移除数组中的obj元素
al.RemoveAt(int index);//移除索引为index的数字元素
al.RemoveRange(int indext,int count);//移除从索引index开始,移除count个元素