题目描述
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
链表结构:
public class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
解析
解法一
- 思路:首先遍历链表,将节点值按照从头到尾的顺序存入ArrayList中,再从后往前遍历ArrayList,将值输入到数组中。(这里的ArrayList解决了不知链表长度无法动态分配数组的问题)。
public int[] reversePrint(ListNode head) {
ArrayList<Integer> list = new ArrayList<>();
while(head!=null) {
list.add(head.val);
head = head.next;
}
int size = list.size();
int[] res = new int[size];
for(int i=0;i<size;i++) {
res[i]=list.get(size-i-1);
}
return res;
}
- 时间复杂度O(N),空间复杂度O(N)
- 优化:将空间复杂度优化至O(1)。即在遍历链表时只计算链表的长度,而不用开辟内存空间存值,这样第二次遍历链表时,按照从头到尾的顺序将值倒序输入到数组中。
public int[] reversePrint(ListNode head) {
if(head==null) return new int[0];
int length=0;
ListNode node = head;
while(node!=null) {
length++;
node = node.next;
}
int[] res = new int[length];
for(int i=length-1;i>=0;i--) {
res[i]=head.val;
head=head.next;
}
return res;
}
解法二:辅助栈
要求从尾到头打印链表,而栈的特点是先入后出,所以可以借助辅助栈。(代码思路和上面是一样的,只是数据结构不同)
public int[] reversePrint(ListNode head) {
Deque<Integer> stack = new ArrayDeque<Integer>();
while(head!=null) {
stack.push(head.val);
head=head.next;
}
int[] res = new int[stack.size()];
for(int i=0;i<res.length;i++) {
res[i]=stack.pop();
}
return res;
}
这里需要注意的是在for循环中,判断条件是i<res.length
,刚开始写成了i<stack.size()
,然而satck在pop出栈元素后,stack的size是变化了的,所以会出错。
- 时间复杂度O(N),空间复杂度O(N)