输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例 1:
输入:head = [1,3,2]
输出:[2,3,1]
限制:
0 <= 链表长度 <= 10000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof
思路1:解决这个问题肯定要遍历链表。遍历的顺序是从头到尾的顺序,可输出的顺序却是从尾到头。也就是说第一个遍历到的结点最后一个输出,而最后一个遍历到的结点第一个输出。这就是典型的“后进先出”,我们可以用栈实现这种顺序。
解法1:
public int[] reversePrint(ListNode head) {
Stack<ListNode> stack=new Stack<>();
ListNode temp=head;
while (temp!=null){
stack.push(temp);
temp=temp.next;//如果往下走 就要用temp来判断是否为null
}
int size=stack.size();
int[] res=new int[size];
//size 一定要提前算出来 不要用stack.size()
for (int i = 0; i < size; i++) {
res[i]=stack.pop().val;
}
return res;
}
思路2:都可以用栈实现了 那么递归也一定是可以的。但是如果链表过长的话。可能会导致函数调用的层级很深,导致函数调用栈溢出,所以用栈的鲁棒性要更好一点。
解法2:
List<Integer> list=new ArrayList<>();
public int[] reversePrint(ListNode head) {
dfs(head);
int len=list.size();
int[] res=new int[len];
for (int i = 0; i <len ; i++) {
res[i]=list.get(i);
}
return res;
}
//递归三要素
void dfs(ListNode node){
//1:终止条件
if (node==null)
return;
//返回值为null 不需要管
dfs(node.next);
//3:本层递归要干什么
list.add(node.val);
}
思路3:有没有更优的呢?发现上两个的空间复杂度都是O(n),假如先遍历这个链表,提前算出这个链表的长度,然后在重新遍历下链表进行赋值是不是可以!看代码!
解法3:
public int[] reversePrint(ListNode head) {
if (head == null)
return new int[0];
ListNode temp = head;
int len=0;
//计算出链表的长度
while (temp != null) {
len++;
temp=temp.next;
}
int[] res=new int[len];
int i=1;
while (head!=null){
res[len-i]=head.val;
head=head.next;
i++;
}
return res;
}
这个应该是最优算法了,空间复杂度O(1) 时间复杂度O(n)!
记录一下,2021.4.5 11:04!天气晴朗,阳光明媚!