题目描述
输入一个链表,从尾到头打印链表每个节点的值
思路分析
看到题目,首先想到的是逆转链表,然后打印,但这样会改变链表结构,明显不符合仅仅“打印”的要求
随后又想到,构造一种数据结构,使得链表数据插入后可以按反序输出,自然就想到了栈
方法一:利用栈的先入后出原则,遍历整个链表后再逐个出栈
方法二:利用递归,(递归本质是栈结构)
方法三:利用ArrayList的add api,循环写法
/**
* Inserts the specified element at the specified position in this
* list. Shifts the element currently at that position (if any) and
* any subsequent elements to the right (adds one to their indices).
*
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
源码如上所示,add(0,"当前节点值")即可实现头插
方法四:先把链表中的值赋给arraylist,然后利用Collectios类的reverse方法反转arraylist即可(也没有改变链表结构啊hhhh)
方法源码如下
/**
* Reverses the order of the elements in the specified list.<p>
*
* This method runs in linear time.
*
* @param list the list whose elements are to be reversed.
* @throws UnsupportedOperationException if the specified list or
* its list-iterator does not support the <tt>set</tt> operation.
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public static void reverse(List<?> list) {
int size = list.size();
if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {
for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)
swap(list, i, j);
} else {
// instead of using a raw type here, it's possible to capture
// the wildcard but it will require a call to a supplementary
// private method
ListIterator fwd = list.listIterator();
ListIterator rev = list.listIterator(size);
for (int i=0, mid=list.size()>>1; i<mid; i++) {
Object tmp = fwd.next();
fwd.set(rev.previous());
rev.set(tmp);
}
}
}
REVERSE_THRESHOLD = 18(由经验得到的值),RandomAccess是标记接口,表示集合类型
简单的说,如果集合类是RandomAccess的实现,
则尽量用for(int i = 0; i < size; i++) 来遍历而不要用Iterator迭代器来遍历
反过来,如果List是Sequence List,则最好用迭代器来进行迭代。
代码
方法一
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
Stack<Integer> stack=new Stack<Integer>();
while(listNode!=null){
stack.push(listNode.val);
listNode=listNode.next;
}
ArrayList<Integer> list=new ArrayList<Integer>();
while(!stack.isEmpty()){
list.add(stack.pop());
}
return list;
}
结果
方法二
/**
* public class ListNode {
* int val;
* ListNode next = null;
*
* ListNode(int val) {
* this.val = val;
* }
* }
*
*/
import java.util.ArrayList;
public class Solution {
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;
}
}
结果
方法三
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> list = new ArrayList<Integer>();
while(listNode != null){
list.add(0,listNode.val);
listNode = listNode.next;
}
return list;
}
结果
方法四
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> list = new ArrayList<Integer>();
while(listNode != null){
list.add(listNode.val);
listNode = listNode.next;
}
Collections.reverse(list);
return list;
}
}