剑指Offer06从尾到头打印链表
1. 问题描述
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例 1:
输入:head = [1,3,2] 输出:[2,3,1]
限制:
0 <= 链表长度 <= 10000
2. 代码实现
2.1 方法一
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public int[] reversePrint(ListNode head) {
// 利用栈先进后出的特点
Stack<ListNode> stack = new Stack<ListNode>();
// 利用temp辅助节点,用来遍历
ListNode temp = head;
while(temp != null){
stack.push(temp);
temp = temp.next;
}
// 获得栈的尺寸
int size = stack.size();
// 获目标数组
int[] result = new int[size];
// 从栈中取数据,放到目标数组中
for (int i = 0; i < size; i++) {
result[i] = stack.pop().val;
}
return result;
}
}
2.2 方法二
优化版的递归
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public int[] reversePrint(ListNode head) {
// 获得链表的长度
int index = getListNodeLength(head);
// 获得数组的长度
int[] result = new int[index];
// 调用递归的方法
reversePrint(head,result,index-1);
return result;
}
/**
* 递归的方法
*/
public void reversePrint(ListNode head,int[] arr,int index){
// 递归结束的条件
if (head == null){
return;
}
reversePrint(head.next,arr,index-1);
// 放到数组里
arr[index] = head.val;
}
/**
*获得链表的长度
*/
public int getListNodeLength(ListNode head){
int count;
if (head != null){
count = 1;
}else {
return 0;
}
ListNode temp = head;
while(temp.next != null){
count++;
temp = temp.next;
}
return count;
}
}
2.3 方法三
反转链表法
- 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
- 内存消耗:39.4 MB, 在所有 Java 提交中击败了73.45%的用户
public ListNode reverseListNode(ListNode head){
// 反转链表的方法
ListNode pre = null;
while(head != null){
// 拿到链表节点除第一个外其余的数据
ListNode next = head.next;
// 拿到链表头和pre
head.next = pre;
// 关键点:pre等于head
pre = head;
// 把链表节点除第一个外其余的数据赋值给head形成新的链表,然后再经过while循环
head = next;
}
return pre;
}
3. 结果分析
方法一:
- 执行用时:1 ms, 在所有 Java 提交中击败了74.30%的用户
- 内存消耗:40.4 MB, 在所有 Java 提交中击败了48.68%的用户
方法二:
- 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
- 内存消耗:41.1 MB, 在所有 Java 提交中击败了10.27%的用户