从尾到头打印链表,此题出自《剑指Offer》
题目:输入一个链表的头节点,按链表从尾到头的顺序返回每个节点的值(用数组返回)
有人可能想直接反转链表啊,但是反转链表就破坏掉了原链表,所以要看要求,如果可以破坏原链表的话2那没问题。
思路1:
我们知道栈是一种先进后出的数据结构,所以我们可以遍历链表把数据入栈然后再出栈。
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> list = new ArrayList<>();
if (listNode == null) {
return list;
}
Stack<Integer> stack = new Stack<>();
while (listNode != null) {
stack.push(listNode.val);
listNode = listNode.next;
}
while (!stack.isEmpty()) {
list.add(stack.pop());
}
return list;
}
思路二:
直接逆置数组,这个也比较简单,定义left和right相遇就停止交换。
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> list = new ArrayList<>();
if (list == null) {
return list;
}
while (listNode != null) {
list.add(listNode.val);
listNode = listNode.next;
}
int left = 0;
int right = list.size()-1;
while (left < right) {
int tmp = list.get(left);
list.set(left,list.get(right));
list.set(right,tmp);
left++;
right--;
}
return list;
}
思路三:
思路三比较巧妙,用递归遍历链表,当遍历到链表的尾部的时候,此时的数据就是末尾的数据,就可以实现从尾到头把数据给添加到顺序表中。不过需要注意的是这个思路可能会爆栈。
public void func(ArrayList<Integer> list,ListNode listNode) {
if (listNode == null) {
return;
}
func(list,listNode.next);
list.add(listNode.val);
}
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> list = new ArrayList<>();
if (listNode == null) {
return list;
}
func(list,listNode);
return list;
}
题目链接:从尾到头打印链表