重做剑指offer(三)——从尾到头打印链表
题目描述:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
分析:题目就一句话,一行都不到,理解起来应该没什么难度,但是有一点是需要注意的,题目要求是从尾到头打印链表,不是从头到尾打印链表。说来惭愧,我第一次看题就看岔了。而对于一般的单链表来说,只能顺序操作,无法逆序。那如果硬是要逆序输出怎么办,这时候栈大喊一声“我来!”,利用栈的先进后出特性,于是问题迎刃而解。
import java.util.Stack;
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
Stack<ListNode> stack = new Stack<ListNode>();
while(listNode != null){
stack.push(listNode);
listNode = listNode.next;
}
ArrayList<Integer> result = new ArrayList<Integer>();
while(!stack.isEmpty()){
result.add(stack.pop().val);
}
return result;
}
}
如《剑指offer》上所说,递归的本质也就是一个栈,所以这题自然可以用递归的方式来实现,在输出当前节点时,利用递归先把它的下一个节点输出,直到写一个节点为空时,就开始一层层输出。与上面方法不一样的是,这样需要把返回都ArrayList设为全局变量。递归实现如下:
import java.util.Stack;
import java.util.ArrayList;
public class Solution {
ArrayList<Integer> re = new ArrayList<Integer>();
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
if(listNode != null){
if(listNode.next != null){
printListFromTailToHead(listNode.next);
}
re.add(listNode.val);
}
return re;
}
}
知识点总结:
Stack<ListNode> stack = new Stack<ListNode>();
上面这行代码中的<……>在JAVA中表示泛型,泛型可以解决数据类型中的安全性问题,上面这行代码表示新建一个空的栈(Stack),并且该栈的每个元素的类型都必须是ListNode类。当然,除了在定义对象时可以利用泛型来声明元素的数据类型,在类和方法的定义上常常用到泛型。
上面的方法中我们还用到了Stack和ArrayList这个两个常用的类,在这里稍微补充一下这两个类的知识:
- Stack:这是数据结构中的栈,大家肯定都非常熟悉,后进先出(FILO, First In Last Out)是它最明显的特性,Stack继承于Vector,Vector是线程安全的,栈的常用API如下
返回值 | 函数名 |
---|---|
boolean | empty() |
E | peek() |
E | pop() |
E | push(E object) |
int | search(Object o) |
- ArrayList:是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长。
和Vector不同,ArrayList中的操作不是线程安全的!所以,建议在单线程中才使用ArrayList,而在多线程中可以选择Vector或者CopyOnWriteArrayList。ArrayList的常用API如下
// Collection中定义的API
返回值 | 函数名 |
---|---|
boolean | add(E object) |
boolean | addAll(Collection<? extends E> collection) |
void | clear() |
boolean | contains(Object object) |
boolean | containsAll(Collection<?> collection) |
boolean | equals(Object object) |
int | hashCode() |
boolean | isEmpty() |
Iterator<E> | iterator() |
boolean | remove(Object object) |
boolean | removeAll(Collection<?> collection) |
boolean | retainAll(Collection<?> collection) |
int | size() |
<T> T[ ] | toArray(T[] array) |
Object[ ] | toArray() |
// AbstractCollection中定义的API
返回值 | 函数名 |
---|---|
void | add(int location, E object) |
boolean | addAll(int location, Collection<? extends E> collection) |
E | get(int location) |
int | indexOf(Object object) |
int | lastIndexOf(Object object) |
ListIterator<E> | listIterator(int location) |
ListIterator<E> | listIterator() |
E | remove(int location) |
E | set(int location, E object) |
List<E> | subList(int start, int end) |
// ArrayList新增的API
返回值 | 函数名 |
---|---|
Object | clone() |
void | ensureCapacity(int minimumCapacity) |
void | trimToSize() |
void | removeRange(int fromIndex, int toIndex) |