題目來源於 LeetCode 上第 206號(Reverse Linked List)問題,題目難度為 Easy,AC率55.2%
題目地址:https://leetcode.com/problems/reverse-linked-list/
題目描述
Reverse a singly linked list.
反轉一個單連結串列
Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL
複製程式碼
解法一: 遞迴
-
尋找遞迴結束條件:當連結串列只有一個節點,或者如果是空表的話,結束遞迴
head == null || head.next == null 複製程式碼
-
呼叫函式本身,傳入下一個節點
reverseList(head.next); 複製程式碼
我們把 2->3->4->5 遞迴成了 5->4->3->2, 對於1節點沒有去更改,所以1的next節點指向的是2,如下所示
遞迴前: 1 -> 2 -> 3 -> 4 -> 5 遞迴後: 1 -> 2 <- 3 <- 4 <- 5 | v null 複製程式碼
-
最後將節點 2 的 next 指向 1,然後把 1 的 next 指向 null,如下所示
null <- 1 <- 2 <- 3 <- 4 <- 5 複製程式碼
演算法效率如下圖所示:
程式碼實現
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null) return head;
ListNode nextNode = reverseList(head.next);
ListNode tempNode = head.next;
tempNode.next = head;
head.next = null;
return nextNode;
}
}
複製程式碼
解法二: 原地逆置連結串列
設定三個節點 preNode, head, next
- 判斷head 以及 head.next 是否為空,如果為空,結束迴圈
- 如果不為空,設定臨時變數next為head的下一個節點
- head的下一個節點指向preNode,然後preNode移動到head, head移動到next
- 重複(1)(2)(3)
演算法效率如下圖所示:
程式碼實現
class Solution {
public ListNode reverseList(ListNode head) {
ListNode preNode = null;
while (head!=null){
ListNode next = head.next;
head.next = preNode;
preNode = head;
head = next;
}
return preNode;
}
}
複製程式碼
解法三:頭插入法逆值連結串列
- 新建一個新連結串列, 新連結串列的頭結點 newHead
- 迴圈判斷head是否為空,為空時結束迴圈
- 如果不為空,依次取原連結串列中的每一個節點,作為第一個節點插入到新連結串列中
演算法效率如下圖所示:
程式碼實現
class Solution {
public ListNode reverseList(ListNode head) {
ListNode newHead = new ListNode(0);
while (head!=null){
ListNode tempNode = new ListNode(head.val);
tempNode.next = newHead.next;
newHead.next = tempNode;
head = head.next;
}
return newHead.next;
}
}
複製程式碼