定義一個函式,輸入一個連結串列的頭節點,反轉該連結串列並輸出反轉後連結串列的頭節點。
示例:
輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL
限制:
0 <= 節點個數 <= 5000
利用外部空間
先申請一個動態擴容的陣列或者容器,比如 ArrayList這樣的,
然後不斷遍歷連結串列,將連結串列中的元素新增到這個容器中。
再利用容器自身的 API,反轉整個容器,這樣就達到反轉的效果了。
最後同時遍歷容器和連結串列,將連結串列的值改為容器的值。
因為此時容器的值為 5 4 3 2 1
。
連結串列按照這個順序重新被設定一遍,就達到要求了。
空間複雜度
O(N)
雙指標法
演算法思想
我們申請兩個指標,一個指標叫 pre
,最初指向 NULL。
第二個指標 cur
指向 head,然後不斷遍歷 cur
。
每次迭代 cur
,都將 cur
的 next
指向 pre
,然後 pre
和 cur
前進一位。
都迭代完了(cur
變成 null 了),pre
就是最後一個節點了。
程式碼
class Solution {
public ListNode reverseList(ListNode head) {
//申請節點,pre和 cur,pre指向null
ListNode pre = null;
ListNode cur = head;
ListNode tmp = null;
while(cur!=null) {
//記錄當前節點的下一個節點
tmp = cur.next;
//然後將當前節點指向pre
cur.next = pre;
//pre和cur節點都前進一位
pre = cur;
cur = tmp;
}
return pre;
}
}
個人理解
從頭遍歷連結串列,修改每個節點的 next
指向的值。
那麼一個節點的新的 next
值是什麼呢,是它的前一個節點,那麼我們把它儲存起來即可,用的時候再取出來該值,所以我們定義了 pre
節點。
那麼我們應該什麼時候給當前節點的 next
節點賦值呢?
我們不能直接執行下面的程式碼 head.next = pre;
,這樣是不可以的,形成閉環了。
所以我們有個臨時變數 tmp
,用來儲存當前節點的 next
的值,首先將 head.next
值取出來,然後將 head.next
賦值為 pre
,再將 tmp
值賦值給 head
,這樣我們就下一層迴圈了。最終獲取最後一個節點,就是反轉連結串列的第一個節點,那能否透過 head
節點獲取這最後一集個節點呢,因為我們的 head
節點是最後一個節點的 next
值,為 null,所以我們取 head.pre
的值就可以了。
上面的程式碼用 cur
來代替 head
。
遞迴法
演算法思想
遞迴的兩個條件:
終止條件是當前節點或者下一個節點==null
在函式內部,改變節點的指向,也就是 head 的下一個節點指向 head 遞迴函式那句
head.next.next = head
程式碼
class Solution {
public ListNode reverseList(ListNode head) {
//遞迴終止條件是當前為空,或者下一個節點為空
if(head==null || head.next==null) {
return head;
}
//這裡的cur就是最後一個節點
ListNode cur = reverseList(head.next);
//這裡請配合動畫演示理解
//如果連結串列是 1->2->3->4->5,那麼此時的cur就是5
//而head是4,head的下一個是5,下下一個是空
//所以head.next.next 就是5->4
head.next.next = head;
//防止連結串列迴圈,需要將head.next設定為空
head.next = null;
//每層遞迴函式都返回cur,也就是最後一個節點
return cur;
}
}
個人理解
終止條件為什麼有兩個?
分別對應著兩種情況:
- 連結串列為空,需要判斷
head==null
- 正常連結串列,需要判斷
head.next==null
head.next.next = head 怎麼理解?**
head.next
是當前節點的下一個節點,這個節點的 next 值就是反過來嘛,就是 head
head.next = null 是什麼意思?**
為了防止閉環。
為什麼會返回 cur?
因為 cur 是最後一層遞迴返回的值,也就是最後一個節點,也是反轉連結串列的第一個節點,所以我們返回這個節點即可。
作者:wang_ni_ma
連結:leetcode-cn.com/problems/fan-zhuan...
來源:力扣(LeetCode)
本作品採用《CC 協議》,轉載必須註明作者和本文連結