剑指 Offer 06. 从尾到头打印链表
题目
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例 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.1 辅助栈
遍历链表,利用一个辅助栈存储链表节点值,然后依次弹出元素到数组中
public class Offer06 {
/**
* v0 使用栈存储并翻转元素顺序
* @param head 链表头部元素
* @return
*/
public int[] reversePrintV0(ListNode head) {
Deque<Integer> stack = new LinkedList<>();
while (head != null) {
stack.push(head.val);
head = head.next;
}
int[] res = new int[stack.size()];
int i = 0;
while (!stack.isEmpty()){
res[i++] = stack.pop();
}
return res;
}
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(n)
代码
public class Offer06 {
/**
* v1 使用ArrayList存储元素,最后翻转为数组
* @param head 链表头部元素
* @return
*/
public int[] reversePrintV1(ListNode head) {
ArrayList<Integer> arrayList = new ArrayList<>();
while (head != null) {
arrayList.add(head.val);
head = head.next;
}
int[] res = new int[arrayList.size()];
int i = 0;
int l = arrayList.size() - 1;
while (i < arrayList.size()){
res[i++] = arrayList.get(l--);
}
return res;
}
}
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(n)
1.2 列表
遍历链表,使用一个 ArrayList 存储元素,然后将值反序填充到数组中
2.题解思路
不借助其他数据结构,先遍历一次链表,得到链表长度并生成对应长度的数组,再遍历一次链表将节点值反序填充到数组中
代码
public class Offer06 {
/**
* 题解思路:不借助其他数据结构的方法,先遍历一遍链表获得链表长度,然后将链表的值反序填充到数组
* @param head
* @return
*/
public int[] reversePrintV3(ListNode head) {
//先获取链表长度,创建对应长度数组
ListNode currNode = head;
int len = 0;
while(currNode != null){
len ++;
currNode = currNode.next;
}
int[] result = new int[len];
//再次遍历链表,将值倒序填充至结果数组
currNode = head;
while(currNode != null){
result[len - 1] = currNode.val;
len --;
currNode = currNode.next;
}
return result;
}
}
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(n)
总结
虽然可以使用其他数据结构帮助解题,但是在思考的过程中也可以尝试使用题目所给的数据结构,或许效率更高?