劍指Offer_#6_從尾到頭列印連結串列
阿新 • • 發佈:2020-07-31
劍指Offer_#6_從尾到頭列印連結串列
劍指offerContents
題目
輸入一個連結串列的頭節點,從尾到頭反過來返回每個節點的值(用陣列返回)。
示例 1:
輸入:head = [1,3,2]
輸出:[2,3,1]
限制:
0 <= 連結串列長度 <= 10000
思路分析
方法1:輔助棧
遍歷連結串列只能從頭到尾,而這裡需要我們從尾到頭列印連結串列的節點,這可以藉助棧的"先進後出"特點來實現。按照正序將各個節點的值入棧,出棧的時候就是倒序的。
方法2:遞迴
演算法流程
先遍歷到連結串列尾部,然後在回溯的過程中把值新增到結果陣列中。
- 終止條件:
head == null
,即遍歷到連結串列的尾部 - 遞推過程:
recur(head.next)
- 回溯過程:
list.add(head)
在遞迴過程中,暫存結果的變數list
可以寫成一個類全域性變數,也可以寫成一個遞迴函式的引數,詳見程式碼。
解答
解答1:輔助棧
class Solution {
public int[] reversePrint(ListNode head) {
Stack<Integer> stack = new Stack<>();
while(head != null){
stack.add(head.val);
head = head.next;
}
int[] res = new int[stack.size()];
for(int i = 0;i <= res.length - 1;i++){
res[i] = stack.pop();
}
return res;
}
}
複雜度分析
時間複雜度:O(n)
空間複雜度:
O(n)
解答2:遞迴
list做全域性變數
class Solution {
List<Integer> list = new ArrayList<>();
public int[] reversePrint(ListNode head) {
//呼叫遞迴函式
recur(head);
//將結果轉換為int陣列
int[] res = new int[list.size()];
for(int i = 0;i <= res.length - 1;i++){
res[i] = list.get(i);
}
return res;
}
private void recur(ListNode head){
//終止條件:已經遍歷到連結串列最尾端
if(head == null) return;
//遞迴呼叫開始,程式在此被阻塞住,直到滿足終止條件,開始回溯
recur(head.next);
//回溯
list.add(head.val);
}
}
list做遞迴方法引數
class Solution {
public int[] reversePrint(ListNode head) {
List<Integer> list = new ArrayList<>();
//呼叫遞迴函式
recur(head, list);
//將結果轉換為int陣列
int[] res = new int[list.size()];
for(int i = 0;i <= res.length - 1;i++){
res[i] = list.get(i);
}
return res;
}
private void recur(ListNode head,List<Integer> aList){
//終止條件:已經遍歷到連結串列最尾端
if(head == null) return;
//遞迴呼叫開始,程式在此被阻塞住,直到滿足終止條件,開始回溯
recur(head.next,aList);
//回溯
aList.add(head.val);
}
}
複雜度分析
時間複雜度:O(n)
,遞迴函式呼叫n次
空間複雜度:O(n)
,遞迴呼叫n次,佔用O(n)
的棧空間