題目描述
輸入一個鏈表的頭節點,從尾到頭反過來返回每個節點的值(用數組返回)。
分析:
問題是鏈表的反向遍歷,於是第一種方法可以將鏈表反轉,然後遍歷即可。
缺點:會破壞原來的鏈表順序。
優點:O(N)的時間複雜度其空間複雜度是O(1);
提到反向,就應該想到一種數據結構——棧,利用棧FILO的特性可以反轉求值。
優點:不會破壞原鏈表,思路簡單,編碼容易。
缺點:需要藉助棧,O(N)的複雜度。如果鏈表過長,性能消耗是一個問題。
遞歸
下面是實現:
鏈表反轉
如何實現鏈表反轉?最簡單的辦法是遍歷節點,然後把該節點放到鏈表最前面,遍歷結束就反轉完畢了。
public int[] reversePrint(ListNode head) {
if (head == null) return new int[0];
ListNode H = head;//H指向頭結點
ListNode N = head.next; //N指向下一個待翻轉的節點
ListNode tmp;//臨時節點
int count=1;//統計節點數量
while (N!=null){
tmp = N;//先把N存起來防止後面修改
head.next = N.next;//head的下一個指向N的下一個(head最終會成爲尾節點)
N.next = H;//N的下一個指向之前的下一個
H =tmp;//N就變成了新的頭結點
N = head.next;//N往後移
count++;
}
int []res = new int[count];
int c = 0;
//遍歷
while(H!=null){
res[c++]=H.val;
H= H.next;
}
return res;
}
性能很好,雙100%;
輔助棧
public int[] reversePrint(ListNode head) {
Stack<Integer> stack = new Stack<>();
while (head!=null){
stack.push(head.val);
head =head.next;
}
int []res = new int[stack.size()];
int index = 0;
while (!stack.isEmpty()){
res[index++] = stack.pop();
}
return res;
}
雖然時間複雜度也是O(N),但是實際上涉及空間分配、棧的操作等,實際表現不是很好。
遞歸