从尾到头打印链表
题目:输入一个链表的头节点,从尾到头反过来打印每个节点的值。
其实有一种偷鸡的方法,因为这道题返回的是一个数组,那么我先把链表的值正序存到数组里,然后将数组翻转返回即可
第一种方法:翻转链表
我的方法:
首先判断这个是不是空对象,是空对象的话,直接返回空数组
再判断 listNode.next 是不是空,是空的说,说明这个链表只有1个值,则add之后直接返回
接着创建了3个对象,分别为 first、second、third。first指向前一个对象,second指向当前对象,third指向后一个对象。
判断second.next是否为空,如果不为空,说明second不是最后一个值。然后先将second.next保存到third中,然后将second.next指向first。 之后让 first 和 second整体向后移一个位置,继续判断。如果second为空,则说明second为最后一个对象,这时候让 second.next指向first,即翻转成功
/**
1. public class ListNode {
2. int val;
3. ListNode next = null;
4. ListNode(int val) {
5. this.val = val;
6. }
7. }
8. */
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> ans = new ArrayList<Integer>(100);
if(listNode == null){
return ans;
}
if(listNode.next == null){
ans.add(new Integer(listNode.val));
return ans;
}
ListNode first = listNode;
ListNode second = first.next;
first.next = null;
ListNode third = null;
while(second.next != null){
third = second.next;
second.next = first;
first = second;
second = third;
}
second.next = first;
while(second != null){
ans.add(new Integer(second.val));
second = second.next;
}
return ans;
}
}
测试用例:
- 功能测试
- 输入的链表有多个节点
- 输入的链表只有1个节点
- 特殊输入测试
- 输入的链表头结点指针为null
简洁版:
其实对于当前指针,只有两种情况,空或不空。这里将其next指向交给下一个循环判断
不空的话,就 next = listNode.next, 这个next 是否为空,交给下一个循环进行判断,这里是将当前对象的next保存下来,然后再让 listNode.next = pre 指向前一个对象。然后让 pre 和 listNode整体向后移动一个位置,再进行判断
空的话,就结束这个修改 next 的循环
ArrayList<Integer> list=new ArrayList<Integer>();
ListNode pre=null;
ListNode next=null;
while(listNode!=null){
next=listNode.next;
listNode.next=pre;
pre=listNode;
listNode=next;
}
while(pre!=null){
list.add(pre.val);
pre=pre.next;
}
return list;
第二种:先进后出,那么就用栈来实现
这里使用了,stack这个包
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
Stack<Integer> myStack = new Stack<Integer>();
ArrayList<Integer> ans = new ArrayList<Integer>(100);
while(listNode != null){
myStack.push(listNode.val);
listNode = listNode.next;
}
while(!myStack.empty()){
ans.add(myStack.pop());
}
return ans;
}
}
第三种:使用递归
判断当前节点是否是空,不是空的话,就将其值加入ans里,然后判断下一个节点是否为空,不为空的话,递归。
这里需要注意的是,ans.add的位置。它的位置是在下一个节点递归结束之后,才add当前节点的val。如果将其放到第二个判断之上,那么返回的结果只有整个链表的最后一个值。
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> ans = new ArrayList<Integer>(100);
if(listNode != null){
if(listNode.next != null){
ans = printListFromTailToHead(listNode.next);
}
ans.add(listNode.val);
}
return ans;
}
}