输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例 1:
输入:head = [1,3,2]
输出:[2,3,1]
限制:
0 <= 链表长度 <= 10000
辅助栈法
链表的特点是必须从前至后访问节点,而题目要求倒序访问,因此想到了先进后出的栈。
时间:入栈出栈共O(N)
空间:数组和栈共O(N)
class Solution {
public int[] reversePrint(ListNode head) {
Stack<Integer>st=new Stack<>();
while(head!=null){
st.push(head.val);
head=head.next;
}
int[] res=new int[st.size()];
for(int i=0;i<res.length;i++){
res[i]=st.pop();
}
return res;
}
}
递归回溯法
写一个递归函数,将数组里的数字层层递归,递归结束的标志是head==null,结束后开始回溯,一个一个写入新的数组中,得到的就是一个倒序的数组。
时间:O(N)
空间:系统递归栈O(N)
class Solution {
public int[] reversePrint(ListNode head) {
ArrayList<Integer>temp=new ArrayList<>();
recur(head,temp);
int []res=new int [temp.size()];
for(int i=0;i<res.length;i++){
res[i]=temp.get(i);
}
return res;
}
void recur(ListNode head,ArrayList temp){
if(head==null) return;
recur(head.next,temp);
temp.add(head.val);
}
}
有没有不需要再遍历一次arraylist的方法?
看评论区大佬的补充,可以不需要遍历。之所以不直接用res去存放倒序后的结果,就是因为不知道有多少个节点,也就不知道res的大小是多少,那么在递归时记录一下现在到第几个节点了,递归终止时也就知道节点的总数量了,这个时候再去初始化res就OK了。其他总体思路都是一样的。
class Solution {
int []res;
int i=0,j=0;
public int[] reversePrint(ListNode head) {
recur(head);
return res;
}
void recur(ListNode head){
if(head==null){
res=new int [i]; //res是一个有i个元素的数组
return;
}
i++; //计数到第几层
recur(head.next);
res[j]=head.val;
j++; //计数到res的第几个元素
}
}