从尾到头打印链表
A:直接反转
A:直接反转当前链表,再对反转后的链接进行操作。
时间复杂度O(n),空间复杂度O(1)
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
if(listNode == null) return new ArrayList<Integer>();
ListNode pre = null, cur = listNode, next = null;
while(cur != null) {
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
ArrayList<Integer> res = new ArrayList<>();
while(pre != null) {
res.add(pre.val);
pre = pre.next;
}
return res;
}
我们还可以利用栈/递归的方式来实现
B:栈
B:栈,利用了栈先进后出的特性。
时间复杂度O(n),空间复杂度O(n)
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
if(listNode == null) return new ArrayList<Integer>();
ListNode pre = null, cur = listNode, next = null;
Stack<Integer> stack = new Stack<>();
while(cur != null) {
stack.push(cur.val);
cur = cur.next;
}
ArrayList<Integer> res = new ArrayList<>();
while(!stack.isEmpty()) {
res.add(stack.pop());
}
return res;
}
C:递归
C:递归,每访问到一个节点,先递归输出后面的节点,再输入该节点。
时间复杂度O(n),空间复杂度O(n)
public void recursionPrint(ListNode listNode) {
if(listNode != null) {
if(listNode.next != null) {
recursionPrint(listNode.next);
}
print(listNode.val + "\t");
}
}
总结:若可以改变链表,A 解法最优;若不可以改变链表,B 解放最优。